Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!cs.utexas.edu!usc!ucsd!helios.ee.lbl.gov!pasteur!agate!shelby!csli!keith From: keith@csli.Stanford.EDU (Keith Nishihara) Newsgroups: comp.lang.c++ Subject: Re: porting tips for c++ Message-ID: <14817@csli.Stanford.EDU> Date: 8 Aug 90 17:25:15 GMT References: <1990Aug6.133901.25745@swbatl.sbc.com> <943@tcs.tcs.com> Sender: keith@csli.Stanford.EDU (Keith Nishihara) Organization: Center for the Study of Language and Information, Stanford U. Lines: 79 X-Local-Date: 8 Aug 90 10:25:15 PDT One correction and a few additional points on this memo. In <943@tcs.tcs.com> gwu@nujoizey.tcs.com (George Wu) writes: > Here's something I wrote up for our people when we switched from GNU >C++ 1.36.2 to Sun C++ (AT&T Cfront 2.0). >FROM: George Wu >DATE: June 27, 1990 >SUBJECT: Switching from GNU C++ to Sun C++ > o Constructors cannot have default argument values. The compiler does > not always complain about this problem. Consider the following > example: > class C { > public: > C(int x = 0); > C(int x, int y = 0); > }; It certainly does allow default values in constructors (as in other functions) but it does not have a rule preferring a non-default argument to a default argument while handling overloading. This applies to all functions, not just constructors. Thus with the definitions above, a call `new C(1)' is ambiguously C(1) or C(1, 0). Gnu resolves this to C(1), preferring the non default argument case. I ran across this problem with varargs optional arguments: void Message(const char *string); void Message(const char *fmt ...); Message("hello"); // Ambiguous. * Sometimes cfront becomes confused about functions and objects having the same name: class Message // etc. class Console { public: void Message(const char *) // etc. Now in functions which are members of Console, attempts to create a new Message objects generate a series of several error messages: void Console::Message(const char *string) { m = new Message(string); } // Error. One fix is to wrap the object in a renamed derived class: class RenamedMessage : public Message {}; void Console::Message(const char *string) { m = new RenamedMessage(string); } // OK. * Friend class declarations are not accepted until the friend class has been seen. * `delete' does not accept pointers to built in types. They must be cast to void *. char *p = new char[20]; delete p; // Bad argument 1 type for op delete. delete (void *)p; // OK. * Casts are not allowed on lvalues. #define IncPtrBytes(p, inc) ((int)(p) += (inc) // Error. * Furthermore the fix I adopted for the above (using overloaded inline functions) compiled, but appears not to work -- the pointer is never incremented at all: inline void IncPtrBytes(char *p, int inc) { p = (char *)((int)p + inc); } inline void IncPtrBytes(short *p, int inc) { p = (short *)((int)p + inc); } etc. I discovered this during a demo on a customer site, when I no longer had the compiler available to investigate. I may be wrong. * If code defining a varargs function is optimised (-O), the varargs stuff no longer works. At best, arguments are not passed. At worst, core dumps result from attempts to call such functions. This problem is potentially the most serious. However it may be that it is due to inclusion of a wrong header file or similar -- I did have some include path confusion when I was trying to do my port, and I did not have time to fix the problem. I had no problems when I left the code unoptimised. Note that the code calling the varargs function may be optimised or not with no change in bahaviour. Neil/.