From: sumatose AT NOSPAM DOT usa DOT net Newsgroups: comp.lang.c++,comp.os.msdos.djgpp,rec.games.programmer Subject: Re: The numer 1 compiler, DJGPP or MSVC Here's a good rating comparision Date: Wed, 17 Sep 1997 04:36:02 -0400 Organization: VTL Lines: 818 Message-ID: References: <3412BD25 DOT 1F30 AT mho DOT net> <5uuqci$15l AT sjx-ixn5 DOT ix DOT netcom DOT com> <34131883 DOT 29A3 AT mho DOT net> <341714E9 DOT F6CC2E67 AT rpi DOT edu> <34184FB9 DOT 441D AT cam DOT org> <34185990 DOT 3DFA AT sensor DOT com> <34189915 DOT 79BB AT cam DOT org> <5vhpcs$sd$1 AT news DOT internetsat DOT com> <341cec0c DOT 0 AT 139 DOT 134 DOT 5 DOT 33> <01bcc1b3$ccb39840$2b40cbc2 AT russnt> <341e2691 DOT 0 AT 139 DOT 134 DOT 5 DOT 33> <341f8541 DOT 0 AT 139 DOT 134 DOT 5 DOT 33> NNTP-Posting-Host: ppp021.216.msherb.videotron.net To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk In group rec.games.programmer, Paul Hsieh says... > On 17 Sep 97 07:22:41 GMT, Herman Schoenfeld said: > > >: ... There are no MSVC compilers for them so any comment comparing > > >: GCC to MSVC is pretty much a waste of bandwidth. > > > > > >Wrong. Some of us can read assembly language files generated by > > >compilers. Some of us can link modules from "foreign" compilers that > > >don't natively target a particular environment. > > > > No, it's not "wrong". MSVC doesn't support linux. Why must you fill this > > newgroup with your lies? > > My understanding is that MSVC's object format is a well documented, > publically known format called "COM" which is not specifically tied to > the Windows operating system. What this means is that you can take code > compiled from C/C++ into .OBJ files, and if you've crafted your own > linker, you can splice them together for whatever OS you want on the x86 > so long as it supports 32 bit FLAT mode programming. That's 'coff' not 'com'. 8-) (about djgpp supporting directx in the future ) > > (ie, full support for windows, full support for directx (if not already)) > > That would be impressive, considering Microsoft is not going to support > them in any way. That's not to say its impossible (reverse engineering > can go a long way) but even WATCOM needed inside information and > cooperation from Microsoft to get Direct X working with their compiler. That's not true. Watcom never needed any inside information. There isn't any inside information to have!! The COM interface can be called by any compiler that support the __stdcall calling convention (passing parameters in the standard C way). Since Watcom has always been able to support OLE, it could call DirectX right away. I think the problem is that you don't know anything about Windows programming at all, and so you make stuff up as you go along. There is nothing voodoo about calling a DirectX functions, and there is nothing special about DirectX that wasn't in MAPI, Video For Windows or other COM-based API that Watcom has supported before. There is nothing to reverse-engineer to call DirectX. >> >Misleading. The patched compiler sometimes (not often) >> produces code that >> >is slower than the original 486 optimizer's code. > More to the point, I believe this compiler can generate code > which is incorrect (that was the status last I checked). Fuck you. The stuff on your web page is completely bogus. Watcom C++ has been plagues like all other C/C++ with 'incorrect code' producted by the optimizer in some cases. It's has had DOZENs AND DOZENs of pathes for it through the years! You're so blinded with MS-Hate, you keep publishing false crap everywhere and say you 'heard people say VC++ 5.0 sucked'. The only reason why Watcom hasn't had as many patches lately is the developement on it is DEAD since Watcom has been bough by PowerSoft. In other words, there're not adding anything new, any new C++ features, just patching up a GUI (PowerBuilder) on top of it and making minor fixes. -=Dead code isn't likely to get new bugs, indeed.=- ************** What's fixed for Watcom C++ 10, patch one (only!): ***************** ** C Compiler ** ***************** The compiler failed to check to see if any variables were defined in the program prior to the first #include directive when asked to use pre-compiled headers. The compiler now checks, and if there are any variables defined before the first #include, then the pre-compiled header will not be used, nor will one be created. =========================================================== Information regarding #pragma disable_message and #pragma enable_message is now saved/restored in pre-compiled header. =========================================================== The scanner lost 2 '?' characters if they were at the end of a 4K input buffer and the next character in the file was also a '?'. =========================================================== _far16 functions that were declared to returned 'int' or 'unsigned int' were being treated as 32-bit return values rather than being treated as 16-bit quantities. =========================================================== ********************* ** Code Generator ** ********************* Calculation of inverse was incorrect when transforming x/k => x*k' with k'=1/k for some powers of 2 (2**n when n > 27). =========================================================== Would get an ICE #44 when putting the address of something into a 16-bit quantity with the 32-bit compiler (never a good thing to do anyway) with a pragma. =========================================================== Fixed a small bug in __far16 callbacks within 32-bit code. They would not work when declared __cdecl. =========================================================== Degenerate loops formed by a bizarre sequence of computed goto's in Fortran would cause compile to GP-fault if loopopts were turned on. =========================================================== Loops with a driving expression which could be determined to be TRUE at compile time would cause code generator to hang in certain situations. =========================================================== Floating point code with thrashing conversions would generate internal compiler errors if compiled for an 8087. =========================================================== A compare of an unsigned type shorter than an int and a constant which could be represented in that type would be done as the original type instead of being promoted to an integer. =========================================================== Fixed a bug involving based pointers and overly-aggresive constant propagation. =========================================================== Fixed a bug where the code generator would pitch a piece of unreferenced stack space which the C++ exception handling required to be there. =========================================================== When trying to hoist floating point instructions out of a loop, it was possible that we would pull a FP register load past an instruction which loaded the segment registers with a value needed by the load instruction. =========================================================== Would try to use SS for a segment override to get at near data in an interrupt function. =========================================================== Optimizer would combine instructions into something which it was no longer able to generate on the Intel architecture, leading to an ICE #28. =========================================================== Division by 0 would be incorrectly folded leading to a GP-fault when -on was specified. =========================================================== Under very strange circumstances, induction variable analysis would introduce a sequence of instructions which would get improperly combined by the register allocator. =========================================================== When unrolling a loop completely, count would be off by one if update of induction variable fell on the wrong side of the loop exit condition. =========================================================== When dealing with extremely tight register situations, it was possible for the code generator to issue an ICE #40 if there were unary ops whose results were short-lived temps. =========================================================== **************** ** C Library ** **************** fixed localtime() function to properly assume that it is not daylight savings time when no rule has been specifed for the conversion to daylight savings time. =========================================================== Cover functions for SetWindowLong and SetClassLong in 386 Windows libraries did not create special thunk when passed the GWL_WNDPROC/GCL_WNDPROC parm. =========================================================== The following files were missing from the 10.0 GA release: src\startup\os2\libmno16.c src\startup\386\initfini.h src\startup\386\cstrto32.asm src\startup\386\cstrtwnt.asm src\startup\386\cstrtwwt.asm src\startup\386\dstrt386.asm src\startup\386\libmno32.c src\startup\386\lmainwnt.c src\startup\386\lmn2wnt.c src\startup\386\dmaino32.c src\startup\386\dmainwnt.c src\startup\386\main2o32.c src\startup\386\main2wnt.c src\startup\386\wmainwnt.c =========================================================== sqrt function in 16-bit floating-point calls library and in 16-bit emulator was missing an instruction to add carry to the next higher word of the result when a word of the result was 0xffff and was incremented. =========================================================== shutdown code for netware would attempt to do too much when terminating early because of memory allocation error. =========================================================== Extended Dos interrupt handlers for SIGINT and SIGBREAK have been fixed. =========================================================== The realloc() code for DOS4/G would corrupt the heap if the pointer passed to realloc() was to the first byte of a system provided memory block and the area of memory following that pointer was also allocated. =========================================================== Thread specific data in multi-thread libraries for OS/2 2.x and Windows NT was being allocated twice in some cases. =========================================================== _Call16 was not saving/restoring EBX, ECX and EDX registers in the Windows supervisor library (lib386\win\win386.lib). =========================================================== exec() calls under DOS were not properly resetting the file handle table in the psp. =========================================================== scanf() class of functions were not counting '%' characters when matched out of the input stream. =========================================================== The _nheapgrow() function was not being called prior to the construction of file scope C++ objects in large data model 16 bit programs. =========================================================== The printf() function within the default windowing system under the 32bit windows supervisor would yield a general protection fault in some cases. =========================================================== DefineUserProc16 for setting up callback functions in 32-bit Windows did not allow for void callback functions. =========================================================== ******************* ** C++ Compiler ** ******************* Throwing some class rvalues caused compiler errors to be generated. class THR { int a }; ... class THR val; throw (THR)val; Work-around: place value in temporary and throw that temporary =========================================================== Destruction with goto's did not always work. No work-around. =========================================================== Return of undefined class value was allowed. Diagnosis has been ungraded. class UNDEF; UNDEF foo(); void goo() { foo(); // now generates an error } =========================================================== Some conversions were missed, causing spurious errors. class X { public: operator int() { return x; } int x; X( int x ) : x(x) {} }; class Y { public: int y; operator X(); Y( int y ) :y(y) {} }; Y a(463); int c = X(a); // a.operator X().operator int() (was diagnosed) =========================================================== Destruction did not always work properly with return statements or goto's nested inside catch blocks. work_around: declare a non-trivial destructable symbol in the block containing the return or goto. =========================================================== Fixed compiler faulting when a macro expansion was incorrectly terminated by the end of the file. work around: fixing error in source eliminates the problem =========================================================== Improved symbol locations for browser information for class definitions that were proceeded by 'class ;' and out of line member function definitions. work around: none =========================================================== Fixed a problem where a conditional expression with ':' operands that contained comma expressions involving a conversion to a common pointer type was issuing an incorrect diagnostic. work around: break up expression into simpler non-comma'd expressions =========================================================== Fixed long double constants so that the value wasn't treated as an integral value. work around: none =========================================================== Fixed compiler generated op= in cases where the class has virtual bases and the actual dynamic type is not the class type (i.e., compiler generated op= could not be used to assign classes that were really base classes if the base class has virtual bases). work around: code a user-defined op= (if possible) =========================================================== Fixed compiler to accept: extern char a[256]; char a[] = { 'a' }; // def'n for 'a[256]' work around: add same size to second array definition =========================================================== Fixed compiler so that storage for constant ints is only reserved if the address is taken. const int x = 5; // no storage req'd const int y = 5; // storage req'd int foo() { return x; } int const *bar() { return &y; } work around: none =========================================================== Fixed some problems with #pragma code_seg and #pragma data_seg that caused page faults in the compiler. work around: none =========================================================== Added support for anonymous structs inside of classes. work around: none =========================================================== Added support for "." as an input file name indicating that stdin should be used. work around: none =========================================================== Fixed problem where command line errors caused "." to be used as an input file giving the appearance that the compiler was in an infinite loop when it really was waiting for user input. work around: none =========================================================== File-scope static functions are made near functions in large code models if: - their address is not taken - multiple code segments are not required - debugging info (-d2) is not needed work around: declare function as explicitly near =========================================================== Improved locations in some diagnostic messages. work around: none =========================================================== Comma operator applied to ellipsis function arguments sometimes skipped the right-hand operand. work around: none =========================================================== Incorrect code was generated for the following case: void foo( const int &r = 1 ); ... foo(); ('r' has the value of the address of the temporary which is incorrect) work around: none =========================================================== Run-time system did not detect throw from "terminate" function when exactly one throw was active. work around: none =========================================================== 386 C++ compiler incorrectly promoted chars and shorts to a 32-bit int when calling a __far16 function. The correct behaviour is to promote them to a 16-bit int. work around: none =========================================================== fixed some problems with the use of typedef'd function types - multiple declarators would lose the function base type - "C++" or "C" linkage in function type would revert to current linkage Example: typedef void VFV(void); extern "C" VFV x,y,z; extern "C" int foo(VFV *); int foo(VFV *v) { v(); return 1; } work around: - break up multiple id declarations into separate single id declarations - match linkage declarations in fn definitions Example: typedef void VFV(void); extern "C" VFV x; extern "C" VFV y; extern "C" VFV z; extern "C" int foo(VFV *); extern "C" int foo(VFV *v) { v(); return 1; } =========================================================== The left-hand side of "." and "->", when the right-hand side was a static member function, was not thrown away when the result was used as a function pointer. This results in incorrect code. work around: remove the left-hand side Example: struct S { static int memb( void ); }; extern S sv; int (*fun)( void ) = &sv.memb; rework last statement to be int (*fun)( void ) = &S::memb; =========================================================== Compiler won't emit warnings 480 and 481 if both declarations are in system header files (i.e., #include ). work around: #pragma warning 480 10 #pragma warning 481 10 =========================================================== Added check in compiler for infinite #include loops. =========================================================== Fixed virtual function thunk generation for functions that pass classes by value and return classes by value. =========================================================== Fixed parsing of ambiguous expressions of the form: ( T

( id ) ) where: T - template id p - template parm id- id arg for constructor =========================================================== Sometimes temporaries in expressions using || or && were not being destructed. Work around: assign left and right sides of expressions to variables. =========================================================== Fixed a problem where cascading errors caused by a missing #include could cause the compiler to fault. =========================================================== Fixed #pragma processing to accept identifiers in upper or lower case. =========================================================== Improved line-number debugging with switch statements and try statements. =========================================================== Sometimes copying of const object to non-const was not diagnosed. =========================================================== Fixed creation of pre-compiled headers that contain object declarations using class templates with address parameters. Example: bug.h template struct S { }; extern int x; extern S<&x> *q; =========================================================== Added stdcall and __stdcall to #pragma processing as known calling conventions. =========================================================== Explicit conversions from a pointer to float, double, and long double were not being diagnosed. =========================================================== Implicit conversion to rvalue of a class conversion to a reference was not handled properly. workaround: Initialize a reference to the conversion as shown in the example below; example: struct D { operator double &(); }; struct S { operator double (); D x; }; S::operator double () #if 0 // replace this code { return x; } #else // by this { double const & r = x; return r; } #endif =========================================================== Fixed a problem where the compiler did not detect that the names of the template arguments during instantiation of a member function where not different than the names used in the class instantiation. Example: // template // work-around template struct Map; Map *z; template struct Map { Key *p; void foo(); Mapping *q; }; template void Map::foo() { } =========================================================== Fixed compiler generation of copy ctor and op= function when inheriting or using a class that has both a const and non-const copy ctor or op= (should default to copy ctor or op= with a const reference parm). Example: struct W { W(); ~W(); W( W const & ); W( W & ); W & operator =( W const & ); W & operator =( W & ); }; struct X : W { // compiler should declare: // X(); // ~X(); // X( X const & ); // X & operator =( X const & ); // was declaring: // X( X & ); // X & operator =( X & ); }; =========================================================== Fixed calling sequence for the following code: struct SubStr { SubStr(); ~SubStr(); SubStr( SubStr const & ); }; struct Str : SubStr { Str(); ~Str(); Str( Str & ); Str( const Str & ); }; struct Sym { Str name; }; int operator ==( SubStr, SubStr ); int bar( Sym *sym, const SubStr &str ) { // should call SubStr copy ctor for both sides // was calling Str copy ctor for left hand side return sym->name == str; } =========================================================== Fixed debugging line numbering for non-brace terminated loops Example: for( i=1; i<10; ++ i ) printf( "in loop\n" ); printf( "out of loop\n" ); The third statement would appear to be within the loop when inspected with the debugger. The code, however, was correct. work around: enclose the statement within the loop with braces. =========================================================== Fixed a problem with destructable static variables inside of member template functions causing incorrect object files to be generated. work around: none =========================================================== Debugging information for class objects passed to functions did not properly indicate when the compiler implicitly converted a pass by value into a pass by reference to temporary. =========================================================== Fixed compiler so that some internal compiler names do not make it into the debugging information. =========================================================== Fixed compiler so that string literals put into the code segment (option -zc) work properly in certain rare cases when debugging -d2. =========================================================== Added support for -ei option so that WATCOM C objects using this option can be used by WATCOM C++. =========================================================== Fixed virtual function table generation so that it doesn't diagnose an ambiguous virtual function override in some complicated hierarchies that depend on dominance for their resolution. Example: struct A { virtual void fn()=0; }; struct B : virtual A { virtual void fn(); }; struct C : virtual B { virtual void fn(); }; struct D : virtual C { virtual void fn(); }; struct E : virtual C {}; struct F : E, D {}; F x;