davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) (10/18/89)
Trying to get a net program working has brought up an interesting question as to what is a constant expression. Background: large program, defines ASCII control characters with a macro as follows: #define CNTL(c) ('c' & 037) While this work fine with pcc, the ANSI preprocessor doesn't expand it. I know that there is now a way to expand to a string, so I looked for the way to expand to a character. I dind't find it. Therefore, rather than plow through thousands of lines of someone else's code to change all occurences, I redefined the macro as: #define CNTL(c) (#c[0] & 037) This expands as follows: CNTL(M) becomes ("M"[0] & 037). No problem, the string is a constant, the subscript is a constant, the octal value is a constant, and the compiler was happy. Except... where the macro was used to initialize a static value, in which case it was "not a constant expression." What am I missing in the standard? In looking up initializers in the index, section 3.5.7 (L14) uses the term "constant expression." However the index doesn't seem to list that term. I looked in the expressions section and didn't find it. Obviously my assumption that it is an expression made up entirely of elements whose value is known at compile time" is incorrect. Don't waste your time telling me that's a bad way to do the macro, I didn't write it, and I don't defend it. -- bill davidsen (davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen) "The world is filled with fools. They blindly follow their so-called 'reason' in the face of the church and common sense. Any fool can see that the world is flat!" - anon
henry@utzoo.uucp (Henry Spencer) (10/19/89)
In article <1219@crdos1.crd.ge.COM> davidsen@crdos1.UUCP (bill davidsen) writes: > What am I missing in the standard? In looking up initializers in the >index, section 3.5.7 (L14) uses the term "constant expression." However >the index doesn't seem to list that term... Wonderful index, that... :-( Try the table of contents: section 3.4 is all about constant expressions. Unfortunately, subscripting a string isn't one. -- A bit of tolerance is worth a | Henry Spencer at U of Toronto Zoology megabyte of flaming. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
diamond@csl.sony.co.jp (Norman Diamond) (10/19/89)
In article <1219@crdos1.crd.ge.COM> davidsen@crdos1.UUCP (bill davidsen) writes: > #define CNTL(c) ('c' & 037) >While this work fine with pcc, the ANSI preprocessor doesn't expand it. Another way around it is to edit all the calls to CNTL(c) to look like CNTL('c'), which isn't too difficult a change. Then the macro depends on neither Reiser nor ANSI stringizing, and the expression is obviously constant. (Uh, obviously, obviously, hmm, can't find "obviously" in the index to the draft standard, bet someone will bite us on this too.) -- Norman Diamond, Sony Corp. (diamond%ws.sony.junet@uunet.uu.net seems to work) Should the preceding opinions be caught or | James Bond asked his killed, the sender will disavow all knowledge | ATT rep for a source of their activities or whereabouts. | licence to "kill".
gwyn@smoke.BRL.MIL (Doug Gwyn) (10/19/89)
In article <1219@crdos1.crd.ge.COM> davidsen@crdos1.UUCP (bill davidsen) writes: > #define CNTL(c) ('c' & 037) > What am I missing in the standard? In looking up initializers in the >index, section 3.5.7 (L14) uses the term "constant expression." However >the index doesn't seem to list that term. Sure it does: constant expressions, 3.4 > Don't waste your time telling me that's a bad way to do the macro, I >didn't write it, and I don't defend it. My recommendation for this abuse of the preprocessor, widely encountered in code from Berkeley UNIX systems, is to change the macro to #define CNTRL(c) ((c) & 037) then globally edit the source code to wrap the arguments with '', e.g. in "ed": g/CTRL(/s/CTRL(\(.\))/CNTRL('\1')/g
davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) (10/19/89)
In article <1989Oct18.224801.1767@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: | | Wonderful index, that... :-( Try the table of contents: section 3.4 is | all about constant expressions. Unfortunately, subscripting a string isn't | one. I blush... I looked in the index and not the TOC. I suspect that I'm not the only one who thinks the index should be about three times longer than it is... I feel particularly dumb because I believe I quoted footnote 44 as part of another posting on sizeof something with a NULL pointer. While the wording in 3.4 is not explicit on this particular case, by looking at what is allowed and forbidden I conclude that "abcd"[1] is not treated as a character constant. It would be nice if it was, but it is treated as if I had said: char nameless[] = "abcd"; char foo = nameless[1]; which clearly isn't allowed for static init. I would like to know if the committee considered the indexed string constant and decided not to make it a special case, or just didn't think of it when doing this section. Obviously it's not one of the common uses ;-) -- bill davidsen (davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen) "The world is filled with fools. They blindly follow their so-called 'reason' in the face of the church and common sense. Any fool can see that the world is flat!" - anon
dan@oresoft.uu.net (Daniel Elbaum) (10/20/89)
In article <1219@crdos1.crd.ge.COM> davidsen@crdos1.UUCP (bill davidsen) writes:
:
: Trying to get a net program working has brought up an interesting
:question as to what is a constant expression.
<the expression>:
: #define CNTL(c) (#c[0] & 037)
:
: This expands as follows: CNTL(M) becomes ("M"[0] & 037). No problem,
:the string is a constant, the subscript is a constant, the octal value
:is a constant, and the compiler was happy. Except... where the macro was
:used to initialize a static value, in which case it was "not a constant
:expression."
:
: What am I missing in the standard? In looking up initializers in the
:index, section 3.5.7 (L14) uses the term "constant expression." However
:the index doesn't seem to list that term. I looked in the expressions
:section and didn't find it. Obviously my assumption that it is an
:expression made up entirely of elements whose value is known at compile
:time" is incorrect.
Referring to the 12/88 dpANS:
It's listed under "constant" in the index, of course. :-)
Section 3.4 describes basically three kinds of constant expressions
that can be used in initializers: arithmetic constants, null pointer
constants, and address constants plus or minus integral constants.
Arithmetic constant expressions can only contain integral constant
operands, so they're out. Address constants point to static storage
or to functions, and can contain [], ., ->, &, and *, but you're not
allowed to use the values of objects obtained by using them.
I guess XJ311 didn't want to bother distinguishing between
constant-pointer-to-constant-object and constant-pointer-to-
arbitrary-object for compile-time rules.
--
Spa link snot the temper tent, a few cannery doubt lowed.
({uunet,tektronix,reed,sun!nosun,osu-cis,psu-cs}!oresoft!(dan)@oresoft.uu.net)
gwyn@smoke.BRL.MIL (Doug Gwyn) (10/20/89)
In article <1262@crdos1.crd.ge.COM> davidsen@crdos1.UUCP (bill davidsen) writes: >In article <1989Oct18.224801.1767@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: >| Wonderful index, that... :-( Try the table of contents: ... > I blush... I looked in the index and not the TOC. Is there something wrong with you guys, or is there a problem in the copy of the draft proposed Standard that you have? The index in my copy does have "constant expressions", right after the list of "constant, ..." entries.
dg@lakart.UUCP (David Goodenough) (10/21/89)
From article <1219@crdos1.crd.ge.COM>, by davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr): > Background: large program, defines ASCII control characters with a > macro as follows: > #define CNTL(c) ('c' & 037) > While this work fine with pcc, the ANSI preprocessor doesn't expand it. This is: 1. Grotesque, 2. Workable. Flame away if you wish, just try it first. #define prequote(x) 'x #define postquote(x) x' #define CNTL(c) ((postquote(prequote(c))) & 0x1f) CNTL(c) Bletch :-/ MAJOR MAJOR PROBLEM - our C compiler (greenhills) likes the useages of postquote and prequote in that order. Some compilers may not care, while others might want them reversed. I think it depends on whether nested macros are expanded from the inside out (as Greenhills does), or outside in. It's probably not portable .... Oh well. -- dg@lakart.UUCP - David Goodenough +---+ IHS | +-+-+ ....... !harvard!xait!lakart!dg +-+-+ | AKA: dg%lakart.uucp@xait.xerox.com +---+
kremer@cs.odu.edu (Lloyd Kremer) (10/21/89)
In article <1219@crdos1.crd.ge.COM> davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) writes: > #define CNTL(c) ('c' & 037) >While this work fine with pcc, the ANSI preprocessor doesn't expand it. > > #define CNTL(c) (#c[0] & 037) > > This expands as follows: CNTL(M) becomes ("M"[0] & 037). >where the macro was >used to initialize a static value, in which case it was "not a constant >expression." > >Obviously my assumption that it is an >expression made up entirely of elements whose value is known at compile >time" is incorrect. This seemed like an interesting question, and I've been waiting for a response from one of the real "legal eagles" of the Standard. But since none is forthcoming, I'll throw in my two cents. The macro contains an array subscripting expression, and the compiler apparently fears that the contents of the array may be changed at run time rendering the expression non-constant. However, notice that the array in question is a *string literal*. What is this compiler's policy regarding the writability of string literals? If they are writable, then the compiler's rejection of the expression is justified. If they are not, then the compiler is simply seeing the subscripting operation, and prematurely giving up hope of constancy. Of course, neither possibility offers a solution. The compiler won't accept to expression as constant. I don't suppose it would do any good to put a "const" into the macro. Just hypothesizing. :-) P.S. I support the adoption of the Standard, but it is disheartening to keep seeing its introduction cause working code to break. Growing pains, I guess. -- Lloyd Kremer ...!uunet!xanth!kremer Have terminal...will hack!
djones@megatest.UUCP (Dave Jones) (10/21/89)
From article <1219@crdos1.crd.ge.COM>, by davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr): > ... > Background: large program, defines ASCII control characters with a > macro as follows: > #define CNTL(c) ('c' & 037) > While this work fine with pcc, the ANSI preprocessor doesn't expand it. How about #define CNTL(c) ((c) & 037) Then change all occurances of the form CNTL(x) into CNTL('x') (Use an AWK program to automate things, if there's a bunch of them.) Ain't that the "right" way to do it?
henry@utzoo.uucp (Henry Spencer) (10/22/89)
In article <11354@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >Is there something wrong with you guys, or is there a problem in the copy >of the draft proposed Standard that you have? The index in my copy does >have "constant expressions"... I can't speak for Bill, but while I'm not impressed with the index in general, it does have this entry in my draft. I didn't bother looking for it at all; it's been a long time since I found the index useful, mostly because I know where things are without it. -- A bit of tolerance is worth a | Henry Spencer at U of Toronto Zoology megabyte of flaming. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
diamond@csl.sony.co.jp (Norman Diamond) (10/23/89)
In article <727@lakart.UUCP> dg@lakart.UUCP (David Goodenough) writes: [regarding ANSIfying the CTRL(c) macro] >Flame away if you wish, just try it first. I can't. I don't have a validated (or even unvalidated-but-asserted) ANSI C compiler. Nonetheless I do finally have a copy of the proposed standard, which in fact is a legal one. (Thanks Steve Friedl.) >#define prequote(x) 'x >#define postquote(x) x' I do not believe that this can possibly work in ANSI C. Consider the following tweaks: #define prequote(x) 'x /* is this a comment? */ #define postquote(x) x' /* is this a comment? */ >#define CNTL(c) ((postquote(prequote(c))) & 0x1f) > >CNTL(c) Now what is the character constant? A single character? A longer string? (with implementation-defined results, especially when it's longer than the number of chars that fit in an int...) >Bletch :-/ True, but that's not the problem at the moment. (In case anyone missed it, the real question is, can that solution really possibly work in ANSI C?) -- Norman Diamond, Sony Corp. (diamond%ws.sony.junet@uunet.uu.net seems to work) Should the preceding opinions be caught or | James Bond asked his killed, the sender will disavow all knowledge | ATT rep for a source of their activities or whereabouts. | licence to "kill".
cpcahil@virtech.uucp (Conor P. Cahill) (10/24/89)
In article <10983@riks.csl.sony.co.jp>, diamond@csl.sony.co.jp (Norman Diamond) writes: > In article <727@lakart.UUCP> dg@lakart.UUCP (David Goodenough) writes: > >#define prequote(x) 'x > >#define postquote(x) x' > > I do not believe that this can possibly work in ANSI C. Consider the > following tweaks: > > #define prequote(x) 'x /* is this a comment? */ > #define postquote(x) x' /* is this a comment? */ But he (dave) didn't put any comments to the right of his example, so as long as there isn't any extra white space to the right of the code, it *should* work (on both pre and post ANSI). Dave gave a good (although yukie) solution to the problem. He didn't claim that you could do anything with his solution and have it still work. -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) (10/25/89)
In article <727@lakart.UUCP>, dg@lakart.UUCP (David Goodenough) writes: | MAJOR MAJOR PROBLEM - our C compiler (greenhills) likes the useages of | postquote and prequote in that order. Some compilers may not care, while | others might want them reversed. I think it depends on whether nested | macros are expanded from the inside out (as Greenhills does), or outside | in. I appreciate the suggestion, but, as you say, it's not portable. Worse than that, it doesn't work on either of the ANSI-filed compilers I tried. Because of the way the macro is called I can't trust any editor to change the code without breaking it, so I did the globals by hand. The true solution would be a character analogy of #arg. -- bill davidsen (davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen) "The world is filled with fools. They blindly follow their so-called 'reason' in the face of the church and common sense. Any fool can see that the world is flat!" - anon