mikem@otc.OZ (Michael Mowbray) (11/19/86)
The following is a list of the bugs I noticed in release 1.1 of the C++ translator. If anyone has noticed other bugs please let me know. (If info like this has already been posted, please forgive me. We've only just started getting this newsgroup into Australia, so I don't know what's gone before.) Before I list the bugs, though, I ought to say that I've been using both release 1.0 and 1.1 seriously for some time now and that the list below should under no circumstances be taken the wrong way. Many of the bugs are non-critical, although it's obviously desirable to fix them. (Is there anyone out there besides Bell Labs who've fixed things in the translator source code?) ******************************************************************************* - Varargs problems. - The current code in the source module error.c has to be re-written to run on certain machines (read Pyramids). This isn't really a bug in the usual sense of the word and Bjarne tells me that he's redesigned error.c. The only reason I'm mentioning this here is that if you have a Pyramid, but couldn't make C++ run, let me know and I'll send you the diff's. ******************************************************************************* - Misleading Error Handling during parsing of class definition class Test { int i; public: Test(int ii = XXX); int showi() { return i; } }; gives the error message: line 6: error: class Test is undefined when it should recognize at line 4 that XXX is undefined. This is usually only a bad problem when your class is big. If you get the message check first that any default arguments that are macros have actually been defined earlier. ******************************************************************************* - Problems with recognition of function types There are some problems when the translator is dealing with pointers to functions with unknown arguments. The problems are summarised in the following program: //--------------------------------------------------------------- typedef void Vfn(...); //--------------------------------------------------------------- // Both the following should be of type Vfn. void f1() { int dummy=1; } void f2(int i) { int dummy = i; } //--------------------------------------------------------------- main() { Vfn* vfp; vfp = f1; // okay. vfp = f2; // gives "bad assignment type" error. // The translator seems to be interpreting the type // void Vfn(...) as void Vfn(), i.e: not remembering // that any arguments are okay. } //--------------------------------------------------------------- ******************************************************************************* - Taking address of non-lvalue (Can be quite serious.) //--------------------------------------------------------- class Crap { int i; public: Crap(int j) { i=j; } Crap operator+(Crap); int operator==(Crap&); }; Crap const nullcrap(0); Crap Crap::operator+(Crap c) { return Crap(i + c.i); } int Crap::operator==(Crap& c) { return i == c.i; } //--------------------------------------------------------- main() { int k; Crap result(-1), c1(1), c2(2); if ((result = c1+c2) == nullcrap) // This line generates wrong code. k = 1; } //--------------------------------------------------------- This generates the following C-code (which I've cb'd and edited to make more readable). The error is at the line following " /*XXXXX*/ " : /* <<cfront 05/20/86>> */ /* < tst1.c */ int *_new(); int _delete(); int *_vec_new(); int _vec_delete(); struct Crap { /* sizeof = 4 */ int _Crap_i; }; struct Crap _Crap__plus(); int _Crap__eq(); struct Crap nullcrap; struct Crap _Crap__plus(_auto_this, _auto_c) register struct Crap *_auto_this; struct Crap _auto_c; { struct Crap _auto__V1; return ((((((struct Crap*)(&_auto__V1))->_Crap_i = (_auto_this->_Crap_i + _auto_c ._Crap_i)), ((struct Crap*)(&_auto__V1)))), _auto__V1); } int _Crap__eq(_auto_this, _auto_c) register struct Crap *_auto_this; struct Crap *_auto_c; { return (_auto_this->_Crap_i == (*_auto_c)._Crap_i); } int main() { _main(); { int _auto_k; struct Crap _auto_result; struct Crap _auto_c1; struct Crap _auto_c2; (((((struct Crap*)(&_auto_result))->_Crap_i = -1), ((struct Crap*)(&_auto_result)))); (((((struct Crap*)(&_auto_c1))->_Crap_i = 1), ((struct Crap*)(&_auto_c1)))); (((((struct Crap*)(&_auto_c2))->_Crap_i = 2), ((struct Crap*)(&_auto_c2)))); /*XXXXX*/ /* In the following line " &(_auto_result = ....) " is ILLEGAL. */ if (_Crap__eq(&(_auto_result = _Crap__plus(&_auto_c1, _auto_c2)), (struct Crap*)(&nullcrap))) _auto_k = 1; /* It should generate something like: */ /* ...((_auto_result = ....), &_auto_result)... */ } }; extern int _STItst1_c_() { (((((struct Crap*)(&nullcrap))->_Crap_i = ((int)0)), ((struct Crap*)(&nullcrap)))); }; /* the end */ ******************************************************************************* ** BUG No6 - code generation fault ** ******************************************************************************* In the following case the C-code generation goes ga-ga: typedef void Vfn(); typedef Vfn *VfnP; void func() { // do nothing. } Vfn* returnVfn() // screws this up { return func; } VfnP returnVfnP() // but this is okay { return func(); } The C-Code generated is: /* <<cfront 05/20/86>> */ /* < tst3.c */ int *_new(); int _delete(); int *_vec_new(); int _vec_delete(); typedef int Vfn(); typedef int (*VfnP)(); int func() { }; int (*returnVfn() /* NICKERS IN A TWIST */ { return (int(*)())(func); } )(); VfnP returnVfnP() /* okay */ { return (int(*)())(func); }; /* the end */ ******************************************************************************* - Visibility problem with protected members. In release 1.1, the new language feature of protected members has been surprisingly useful for me. (More so than I would have anticipated.) One bug I've found is that friends of a derived class can't access inherited protected members. E.g: class Base { protected: int somemember; public: Base(int i) { somemember=i; } }; class Derived : public Base { friend class OtherClass; }; class OtherClass { int i; public: void set_i(Derived& d) { i = d.somemember; } }; - This gives the error message: line 15: error: somemember is protected ******************************************************************************* Mike Mowbray Senior Engineer Systems Development Overseas Telecommunications Commission (Australia) UUCP: {seismo,mcvax}!otc.oz!mikem ACSnet: mikem@otc.oz