ridoux@irisa.fr (Olivier Ridoux) (09/06/90)
Hello, I'd like to know about the portability of expressions of the form `` &^n*^n x '' (`` &*x '', `` &&**x '', `` &&&***x '', ...). An expression of the form `` &&x '' seems to make no sense, since `` & '' requires a lvalue though it yields no lvalue. So `` &&**x '' seems to be ruled out. However, `` &*x '' and `` x '' have the same value though `` x '' may be a lvalue and `` &*x '' cannot if `` & '' is interpreted conservatively. So expressions of the form `` &^n*^n x '' can be reduced to `` x '' through algebraic manipulation. One can even consider that `` &^n*^n x '' has the lvalue-ness of `` x '' (in contrast with the conservative interpretation of `` & ''). The gcc compiler performs this algebraic simplification. My question is: can a programmer expect that every C compiler will perform the algebraic simplification of `` &^n*^nx '' to `` x '', and what will be the lvalue-ness of the expression ? I thank you in advance, Olivier Ridoux
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (09/07/90)
In article <1990Sep6.091605.15732@irisa.fr> ridoux@irisa.fr (Olivier Ridoux) writes:
[ is &&&&&&******x portable? ]
No. Even if ******x has a meaning, its && does not.
[ x is &*x, so x is &&&&&*****x by ``algebraic manipulation'' ]
No. You can reduce &*&*&*&*&*&*&*x to x, given x of a pointer type. But
you can't apply ``algebraic manipulation'' to meaningless expressions.
---Dan
datanguay@watmath.waterloo.edu (David Adrien Tanguay) (09/07/90)
In article <1990Sep6.091605.15732@irisa.fr> ridoux@irisa.fr (Olivier Ridoux) writes: |I'd like to know about the portability of expressions of the form |`` &^n*^n x '' (`` &*x '', `` &&**x '', `` &&&***x '', ...). | |An expression of the form `` &&x '' seems to make no sense, since `` & '' |requires a lvalue though it yields no lvalue. So `` &&**x '' seems to be |ruled out. Also note that the "&&" sequences in the above expressions will lex as "logical and" operators. -- David Tanguay Software Development Group, University of Waterloo
ridoux@irisa.fr (Olivier Ridoux) (09/07/90)
From article <1990Sep7.021321.18381@watmath.waterloo.edu>, by datanguay@watmath.waterloo.edu (David Adrien Tanguay): > In article <1990Sep6.091605.15732@irisa.fr> ridoux@irisa.fr (Olivier Ridoux) writes: > |`` &^n*^n x '' (`` &*x '', `` &&**x '', `` &&&***x '', ...). > > Also note that the "&&" sequences in the above expressions will lex as > "logical and" operators. I apologize. I should have fully parenthesized all the expressions. Since I was only dealing with operators `` & '' and `` * '' I thought it was unambiguous. `` && '' must not interfer in the game. My question is not on the validity of the composition of the operator `` & ''. It is rather "what is the rational of the cc and gcc compilers (sun4) that makes them accept the following program. Can I expect that every C compiler will have the same rational ? My opinion is that the rational is based on the axiom: `` &(*(x)) = x ''. Note that this axiom is not a consequence of the book (K&R). main() { char c = 'c' ; char * pc = &c ; char ** ppc = &pc ; char d = 'd' ; char * pd = &d ; char ** ppd = &pd ; printf( "%c\n", *(*( &(&(*(*(ppc)))) )) ); /* 1 */ printf( "%c\n", *(*( &(&(*(*(ppd)))) )) ); /* 2 */ &(&(*(*(ppc)))) = ppd ; printf( "%c\n", *(*( &(&(*(*(ppc)))) )) ); /* 3 */ } 1 (and 2) shows that the composition of `` & '' is interpreted by the compiler, though the book says it is not valid because `` & '' requires a lvalue and yields no lvalue. 3 shows that the expression `` &(&(*(*(ppc)))) '' is even an lvalue. I think it is because `` ppc '' is an lvalue. Olivier Ridoux
rankin@eql.caltech.edu (Pat Rankin) (09/08/90)
In article <1990Sep7.080855.24070@irisa.fr>, ridoux@irisa.fr (Olivier Ridoux) writes... [...] >My question is not on the validity of the composition of the operator `` & ''. >It is rather "what is the rational of the cc and gcc compilers (sun4) that >makes them accept the following program. Can I expect that every C compiler >will have the same rational ? VAXC (VMS) rejects it: [...] > printf( "%c\n", *(*( &(&(*(*(ppc)))) )) ); /* 1 */ %CC-E-INVOPERAND, Invalid operand of a "& (address-of)" operator. (Same error repeated for the other similar lines. VAXC V3.1) Pat Rankin, rankin@eql.caltech.edu
throopw@sheol.UUCP (Wayne Throop) (09/10/90)
> From: ridoux@irisa.fr (Olivier Ridoux) > "what is the rational of the cc and gcc compilers (sun4) that > makes them accept the following program. Presumably, merely because they are buggy compilers. > Can I expect that every C compiler will have the same rational ? I certainly hope not. It seems to me that about the only way that allowing &(&(...)) makes any sense at all is as part of a larger picture that supports the operation of essentially all "lvalue" requiring operators on value arguments. This larger context would have to deal with rules for things like when, how, and for how long "pseudo-objects" would be created so that lvalue-requiring semantics could be meaningful. It might improve the language in some ways. I emphasize: "might". Now, on the other hand, I ran this program through microsoft C, feeling confident that it would be flagged as erronious. To my surprise and amazement, it ran just as Olivier describes. No slips, no drips, (and worst) no errors. This is apparently a VERY common bug. It shakes my faith in the competence of C implementors. Unless I'm missing something quite major...??? (the program in question:) main() { char c = 'c' ; char * pc = &c ; char ** ppc = &pc ; char d = 'd' ; char * pd = &d ; char ** ppd = &pd ; printf( "%c\n", *(*( &(&(*(*(ppc)))) )) ); /* 1 */ printf( "%c\n", *(*( &(&(*(*(ppd)))) )) ); /* 2 */ &(&(*(*(ppc)))) = ppd ; printf( "%c\n", *(*( &(&(*(*(ppc)))) )) ); /* 3 */ } -- Wayne Throop <backbone>!mcnc!rti!sheol!throopw or sheol!throopw@rti.rti.org
scjones@thor.UUCP (Larry Jones) (09/10/90)
In article <0926@sheol.UUCP>, throopw@sheol.UUCP (Wayne Throop) writes: > [ about compilers allowing "&(&(&(***x)))" ] > This is apparently a VERY common bug. It shakes my faith in > the competence of C implementors. Unless I'm missing something > quite major...??? It's a very easy mistake to make. Since both &* and *& are essentially noops, most compilers will remove adjacent pairs as part of the optimization of expression trees. Since tree rewriting is generally iterative, this results in all such pairs being removed. Semantic restrictions (like lvalueness) are generally not tested until after rewriting, so bogus code like this slips through. ---- Larry Jones UUCP: uunet!sdrc!thor!scjones SDRC scjones@thor.UUCP 2000 Eastman Dr. BIX: ltl Milford, OH 45150-2789 AT&T: (513) 576-2070 Why can't I ever build character in a Miami condo or a casino somewhere? -- Calvin
sa1z+@andrew.cmu.edu (Sudheer Apte) (09/11/90)
throopw@sheol.UUCP (Wayne Throop) writes: > > From: ridoux@irisa.fr (Olivier Ridoux) > > "what is the rational of the cc and gcc compilers (sun4) that > > makes them accept the following program... > ... > Now, on the other hand, I ran this program through microsoft C, > feeling confident that it would be flagged as erronious. To my > surprise and amazement, it ran just as Olivier describes. No > slips, no drips, (and worst) no errors. > > This is apparently a VERY common bug. It shakes my faith in > the competence of C implementors. Unless I'm missing something > quite major...??? You are quite correct. GNU's gcc compiles it without a peep! What is going on? The standard seems quite clear about this, but I've never known gcc to misbehave before... Sudheer. ------------------ The program: main() { char c = 'c' ; char * pc = &c ; char ** ppc = &pc ; char d = 'd' ; char * pd = &d ; char ** ppd = &pd ; printf( "%c\n", *(*( &(&(*(*(ppc)))) )) ); /* 1 */ printf( "%c\n", *(*( &(&(*(*(ppd)))) )) ); /* 2 */ &(&(*(*(ppc)))) = ppd ; printf( "%c\n", *(*( &(&(*(*(ppc)))) )) ); /* 3 */ } ...{harvard, uunet}!andrew.cmu.edu!sa1z sa1z%andrew@CMCCVB.BITNET
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (09/11/90)
In article <0926@sheol.UUCP> throopw@sheol.UUCP (Wayne Throop) writes:
[ that if a compiler reduces &&**x to x then it is buggy ]
Question for the standards people: Is && undefined, unspecified,
implementation-defined, or what have you? Unless it's simply erroneous,
compilers that always delete &* or *& are only being efficient, and
Wayne's faith in the competence of compiler designers should remain
firm.
---Dan
browns@iccgcc.decnet.ab.com (Stan Brown, Oak Road Systems) (09/12/90)
In article <20757:Sep1115:30:0390@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > > Question for the standards people: Is && undefined, unspecified, > implementation-defined, or what have you? See page 49 of K&R 1, or page 53 of K&R 2. Stan Brown, Oak Road Systems, Cleveland, Ohio, U.S.A. (216) 371-0043 The opinions expressed are mine. Mine alone! Nobody else is responsible for them or even endorses them--except my cat Dexter, and he signed the power of attorney only under my threat to cut off his Cat Chow!
karl@haddock.ima.isc.com (Karl Heuer) (09/12/90)
In article <20757:Sep1115:30:0390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >In article <0926@sheol.UUCP> throopw@sheol.UUCP (Wayne Throop) writes: > [ that if a compiler reduces &&**x to x then it is buggy ] > >Question for the standards people: Is && undefined, unspecified, >implementation-defined, or what have you? Applying "&" to an operand that is neither a function designator nor an lvalue violates a constraint (3.3.3.2). Therefore, a conforming implementation is required to diagnose an error. (As with all such diagnostics, it is permissible for it to be a mere warning; the implementation need not abort the compilation if it chooses to support the extension that "&*x" is an lvalue.) Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (09/12/90)
In article <853.26ed0446@iccgcc.decnet.ab.com> browns@iccgcc.decnet.ab.com (Stan Brown, Oak Road Systems) writes: > In article <20757:Sep1115:30:0390@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > > Question for the standards people: Is && undefined, unspecified, > > implementation-defined, or what have you? > See page 49 of K&R 1, or page 53 of K&R 2. K&R1 is obviously an incorrect answer, as I was wondering exactly what level of error-ness &(&(...)) has under ANSI. I don't have K&R2 (does it really indicate specific error levels?) or the standard, which is why I was asking in the first place. I can believe that it's simply erroneous, as it's easy enough for the compiler to detect. In that case compilers that accept it really are broken. But is that what the standard settled on? This is an extremely important question, by the way, as several implementations would apparently be in violation of conformance if && isn't just undefined. They'd be misusing the ``ANSI C'' trademark, and probably be guilty of false advertising, and maybe even tax evasion. Remember, this is the very first hint that a compiler might not be perfectly designed and programmed, or that the implementors might be so ridiculously incompetent that their programs actually show a b-b-b-bug. *Extremely* important. *Extremely* incompetent. (Okay, Dan, cut...) ---Dan
pds@lemming.webo.dg.com (Paul D. Smith) (09/12/90)
In some article, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: []> > Question for the standards people: Is && undefined, unspecified, []> > implementation-defined, or what have you? []> See page 49 of K&R 1, or page 53 of K&R 2. [] []K&R1 is obviously an incorrect answer, as I was wondering exactly what []level of error-ness &(&(...)) has under ANSI. I don't have K&R2 (does it []really indicate specific error levels?) or the standard, which is why I []was asking in the first place. [] [...] [] []---Dan Well, I have K&R II, and I didn't see anything on p. 53 which related to this question ?? However, I did look up some stuff in the reference (Appendix A), which is where all quotes from K&R II about the ANSI standard should come from, anyhoo ... (emphasis added by me) Sec. A7.4.2 "Address Operator" (p. 203) ... --> The operand must be an lvalue <-- referring neither to a bit-field nor to an object declared as register, or must be of function type. Sec. A7.4.3 "Indirection Operator" (p. 204) ... The unary * operator denotes indirection ... --> It is an lvalue if the operand is a pointer to an object of arithmetic, structure, union, or pointer type <-- So, what does this mean? This means that struct foo *ptr, *ptr2; ptr2 = &*ptr; is definitely legal. Unfortunately, Sec A7.4.2 does not explicitly state whether or not "&foo" is an lvalue, although all common sense would indicate that it is not (can you write "&foo = barp"? I think not!) However, "*" _can_ be applied to something which is not an lvalue (eg. the name of an array!), and it generates an lvalue. So, ptr = &&&&****ptr2; is *not* legal (which is fairly intuitive), however it seems that ptr = &*&*&*&*ptr2; _is_ legal. Whatcha think? paul ----- ------------------------------------------------------------------ | Paul D. Smith | pds@lemming.webo.dg.com | | Data General Corp. | | | Network Services Development | "Pretty Damn S..." | | Open Network Applications Department | | ------------------------------------------------------------------
timr@gssc.UUCP (Tim Roberts) (09/12/90)
In article <20757:Sep1115:30:0390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >In article <0926@sheol.UUCP> throopw@sheol.UUCP (Wayne Throop) writes: > [ that if a compiler reduces &&**x to x then it is buggy ] > >Question for the standards people: Is && undefined, unspecified, >implementation-defined, or what have you? Of course && is defined! It's the logical "AND" operator! :-) And now, back to our regularly scheduled debate.
mwp@ubeaut.oz.au (Michael Paddon) (09/20/90)
From article <165@thor.UUCP>, by scjones@thor.UUCP (Larry Jones): > It's a very easy mistake to make. Since both &* and *& are > essentially noops, Beware that this is not the case on some architectures. A case in point is the NCR 32/850 where a location can have two addresses, one in local memory and one in multibus address space. You wouldn't believe the grief this can cause... Michael ------------------------------------------------------------------- | | Internet: paddon@meo78b.enet.dec.com | | | ACSnet: mwp@ubeaut.oz.au | | Michael Paddon | ACSnet: mwp@munnari.oz.au | | | EasyNet: meo78b::paddon | | | Voice: +61 3 895 9392 | -------------------------------------------------------------------
johnhi@teksce.SCE.TEK.COM (John Higley) (09/27/90)
As an experiment, I took the program and fed it to Saber-C. Using the browsing tool and a lot of printing, I discovered that each of the & operators returned an L-value. Going further, I found that the last one did not. Here are the results and a little picture: addr name contents __________ 2cf | d |'d'| ---------- 2d0 |pd |2cf| ---------- 2d4 |ppd |2d0| ---------- print &(*(*(ppd))) --> 2cf print &(&(*(*(ppd)))) --> 2d0 print &(&(&(*(*(ppd))))) --> 2d4 print &(&(&(&(*(*(ppd)))))) --> An lvalue (addressable object) is required. John Higley Tektronix, Inc. Component Engineering Group johnhi@teksce.SCE.TEK.COM