deb@svax.cs.cornell.edu (David Baraff) (10/03/89)
C++ 1.2 emits the following peice of C code often: it is annoying because some C compilers (i.e. mine, HP-UX 800) don't handle it. The construct is &(f()) where f() returns (usually) a structure. The C compiler says error: Address operator requires an lvalue. Now, I don't want to start a debate over whether or not this is legal C -- the question is, does C++ 2.0 emit this sort of C code, and if so, is there a way to stop it? I notice in the 2.0 release notes the variable "FDOTRIGHT"; but this doesn't look like it would help (although the HP-UX C compiler DOES allow the f().x expression). Any C++ 2.0 authors out there who can answer this one? Thanks, David Baraff deb@cs.cornell.edu
jima@hplsla.HP.COM (Jim Adcock) (10/05/89)
My C++ 2.0 compiler [an s300 version] doesn't accept this construct -- squawking about not a lvalue. NOTE: I said the <C++ 2.0 compiler> NOT the backend C compiler won't accept this -- my s300 C compiler will accept the construct. g++ 1.35.x will accept the construct. To my way of thinking, not accepting a structure returned from a function as an lvalue makes perfect sense. Or alternately, letting a returned structure be an lvalue makes no more or less sense than letting a returned "int" be an lvalue. Compilers should be free to use a registered return value protocol for small structures. Requiring a returned value to be an lvalue prevents this [or at least complicates it greatly.] Return a reference instead. References are lvalues. See "thingcopy" verses "badcopy" below. See example program below: #include <stdio.h> class thing { const char* const name; public: thing(char* nm):name(nm){} thing(const thing& that):name(that.name){} void print(){printf("thing is named: %s\n",name);} friend thing& thingcopy(const thing& that) {return *(new thing(that));} friend thing badcopy(const thing& that) {return that;} }; main() { thing* p; thing amagig("IamAgig"); p = &(thingcopy(amagig)); p->print(); // p = &(badcopy(amagig)); C++ 2.0 complains: not an lvalue p->print(); }
shankar@hpclscu.HP.COM (Shankar Unni) (10/05/89)
> &(f()) > C -- the question is, does C++ 2.0 emit this sort of C code, and if > so, is there a way to stop it? I notice in the 2.0 release notes As far as I know, this particular abomination has been fixed in 2.0. We have not encountered it yet. ----- Shankar Unni E-Mail: Hewlett-Packard California Language Lab. Internet: shankar@hpda.hp.com Phone : (408) 447-5797 UUCP: ...!hplabs!hpda!shankar
deb@svax.cs.cornell.edu (David Baraff) (10/05/89)
In article <6590277@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes: >My C++ 2.0 compiler [an s300 version] doesn't accept this construct -- >squawking about not a lvalue. > >NOTE: I said the <C++ 2.0 compiler> NOT the backend C compiler won't accept >this -- my s300 C compiler will accept the construct. > >g++ 1.35.x will accept the construct. > >To my way of thinking, not accepting a structure returned from a function >as an lvalue makes perfect sense. Or alternately, letting a returned >structure be an lvalue makes no more or less sense than letting a >returned "int" be an lvalue. Compilers should be free to use a registered >return value protocol for small structures. Requiring a returned value >to be an lvalue prevents this [or at least complicates it greatly.] > >Return a reference instead. References are lvalues. See "thingcopy" verses >"badcopy" below. Perhaps I didn't make the problem clear enough. It was the 1.2 C++ compiler that emitted this code -- NOT me. All I was doing was writing some standard matrix/vector stuff and I found that the C code emitted contained these &f() constructs -- the original C++ code had nothing resembling them! So the 1.2 compiler emits bad C code. Original q: does the 2.0 compiler ever do this?
jima@hplsla.HP.COM (Jim Adcock) (10/07/89)
>Perhaps I didn't make the problem clear enough. It was the 1.2 >C++ compiler that emitted this code -- NOT me. All I was doing >was writing some standard matrix/vector stuff and I found >that the C code emitted contained these &f() constructs -- the original >C++ code had nothing resembling them! >So the 1.2 compiler emits bad C code. Original q: does the 2.0 compiler >ever do this? According to Shankar, no. I was assuming that if 2.0 wouldn't accept a construct, it ought to be smart enough not to emit it either. So both by practical experience, and my indirect test, the answer seems to be that 2.0 has fixed this.
shankar@hpclscu.HP.COM (Shankar Unni) (10/07/89)
> So the 1.2 compiler emits bad C code. Original q: does the 2.0 compiler > ever do this? As I said previously: No. We have not yet encountered a case where 2.0 generates this type of code. ----- Shankar Unni E-Mail: Hewlett-Packard California Language Lab. Internet: shankar@hpda.hp.com Phone : (408) 447-5797 UUCP: ...!hplabs!hpda!shankar
rfg@ics.uci.edu (Ronald Guilmette) (10/08/89)
In article <6590285@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes: > >... I was assuming that if 2.0 wouldn't accept a >construct, it ought to be smart enough not to emit it either. One would hope so. One would also hope that Cfront would be smart enough to avoid emitting code that your native C compiler will subsequently choke on. Unfortunately, this is not always true. Try this little gem (but first make sure that your CC script does *not* invoke the GNU C compiler): int i; int main () { i = sizeof (main); return 0; } // rfg
shankar@hpclscu.HP.COM (Shankar Unni) (10/10/89)
> Try this little gem (but first make sure that your CC script does *not* > invoke the GNU C compiler): > > int i; > int main () > { > i = sizeof (main); > return 0; > } I got perfectly reasonable code from 2.0 (formatting cleaned up): int main () { _main(); { i = (sizeof main ); return (int )0 ; } } Looks kosher. You mean your compiler choked on "(sizeof main)"? ----- Shankar Unni E-Mail: Hewlett-Packard California Language Lab. Internet: shankar@hpda.hp.com Phone : (408) 447-5797 UUCP: ...!hplabs!hpda!shankar
shankar@hpclscu.HP.COM (Shankar Unni) (10/12/89)
> i = sizeof (main);
Corrections from our ANSI C expert:
This expression is not legal, according to the ANSI C standard (function
names are not converted to pointers to functions when they are arguments to
the "sizeof" operator (section 3.2.2.1), and there is a constraint under
the sizeof operator (section 3.3.3.4) that specifically forbids expressions
of function type).
So cfront should catch this expression and flag it as an error. If it intends
for "main" to be converted to a function pointer, it should emit explicit
C code to do that ("&main") (which, in my opinion, would be a bad thing to
do). If not, it should flag the error.
I stand corrected.
-----
Shankar Unni E-Mail:
Hewlett-Packard California Language Lab. Internet: shankar@hpda.hp.com
Phone : (408) 447-5797 UUCP: ...!hplabs!hpda!shankar
rfg@ics.uci.edu (Ron Guilmette) (10/12/89)
In article <1000032@hpclscu.HP.COM> shankar@hpclscu.HP.COM (Shankar Unni) writes: >> Try this little gem (but first make sure that your CC script does *not* >> invoke the GNU C compiler): >> >> int i; >> int main () >> { >> i = sizeof (main); >> return 0; >> } > >I got perfectly reasonable code from 2.0 (formatting cleaned up): > > int main () > { > _main(); > { > i = (sizeof main ); > return (int )0 ; > } > } > >Looks kosher. You mean your compiler choked on "(sizeof main)"? You mean that yours didn't???? Maybe you had better have a look at the ANSI C (draft) standard. // rfg