ORC Owl Logo 2  

Owl River Company

 
  Your IP is: 54.159.186.7

   snapshotted September 26 2002

   This is G o o g l e's cache of http://www.bero.org/gcc296.html.
   G o o g l e's cache is the snapshot that we took of the page as we crawled the web.
   The page may have changed since that time. Click here for the current page without highlighting.
   To link to or bookmark this page, use the following url:
   http://www.google.com/search?q=cache:14MxugUNW6gC:www.bero.org/gcc296.html+bero+gcc+2.96&hl=en&ie=UTF-8

            Google is not affiliated with the authors of this page nor responsible for its content.

   These search terms have been highlighted:  bero  gcc  2.96 
     ____________________________________________________________________________________________________

                                                   gcc 2.96-RH

  Comment on the accusations of Red Hat Linux 7.x using a buggy or not standards compliant compiler

   First  of all, this is not an official Red Hat statement. Anything said here is purely my own opinion and
   not  necessarily Red Hat's. I happen to work for Red Hat, but this does not mean I have to agree with (or
   do agree with) everything Red Hat does.

   For  instance,  I  wholeheartedly  disagree  about  Red Hat's choice of default desktops (GNOME is ok and
   should  definitely  be  included, but KDE 2.x/3.x has a lot more interesting features (e.g. the Konqueror
   web browser/file manager) and is more friendly to newbies, therefore IMO it should be the default).

   The choice of compilers is an entirely different thing though:
     * gcc  2.96 is actually more standards compliant than any other version of gcc released at the time Red
       Hat made this decision (3.0 is even more compliant, but not as stable yet).
       It  may  not be "standards compliant" as in "what most others are shipping", but 2.96 is almost fully
       ISO C99 and ISO C++ 98 compliant, unlike any previous version of gcc.
     * gcc  2.96  has  more complete support for C++. Older versions of gcc could handle only a very limited
       subset of C++.
       Earlier versions of g++ often had problems with templates and other valid C++ constructs.
     * Most  of  gcc  2.96's perceived "bugs" are actually broken code that older gccs accepted because they
       were not standards compliant - or, using an alternative term to express the same thing, buggy.
       A C or C++ compiler that doesn't speak the standardized C language is a bug, not a feature.
       In the initial version of gcc 2.96, there were a couple of other bugs. All known ones have been fixed
       in  the  version from updates - and the version that is in the current beta version of Red Hat Linux.
       The  bugs in the initial version don't make the whole compiler broken, though. There has never been a
       100% bug free compiler, or any other 100% bug free non-trivial program.
       The  current  version  can be taken from Red Hat Linux 7.2. It will work without changes on prior 7.x
       releases of Red Hat Linux.
       Since  a lot of people claim 2.96 is buggy because of the accusations found in MPlayer documentation,
       I have included the facts that led them to incorrectly believe that 2.96 is buggy here.
     * gcc 2.96 generates better, more optimized code.
     * gcc  2.96  supports  all  architectures  Red  Hat  is  currently supporting, including ia64. No other
       compiler  can  do  this. Having to maintain different compilers for every different architecture is a
       development (find a bug, then fix it 4 times), QA and support nightmare.
     * The binary incompatibility issues are not as bad as some people and companies make you believe.
       First  of  all,  they  affect  dynamically  linked  C++  code  only. If you don't use C++, you aren't
       affected. If you use C++ and link statically, you aren't affected.
       If  you  don't  mind  depending  on  a  current  glibc, you might also want to link statically to c++
       libraries  while linking dynamically to glibc and other C libraries you're using: g++ -o test test.cc
       -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic (Thanks to Pavel Roskin for pointing this out)
       Second,  the  same  issues appear with every major release of gcc so far. gcc 2.7.x C++ is not binary
       compatible  with gcc 2.8.x. gcc 2.8.x C++ is not binary compatible with egcs 1.0.x. egcs 1.0.x C++ is
       not  binary  compatible  with  egcs 1.1.x. egcs 1.1.x C++ is not binary compatible with gcc 2.95. gcc
       2.95 C++ is not binary compatible with gcc 3.0.
       Besides,  it  can easily be circumvented. Either link statically, or simply distribute libstdc++ with
       your  program and install it if necessary. Since it has a different soname, it can coexist with other
       libstdc++ versions without causing any problems.
       Red  Hat Linux 7 also happens to be the first Linux distributions using the current version of glibc,
       2.2.x.  This update is not binary compatible with older distributions either (unless you update glibc
       -  there's  nothing that prevents you from updating libstdc++ at the same time), so complaining about
       gcc's  new  C++  ABI  breaking binary compatibility is pointless. If you want to distribute something
       binary-only, link it statically and it will run everywhere.
       Someone has to be the first to take a step like this. If nobody dared to make a change because nobody
       else  is doing it, we'd all still be using gcc 1.0, COBOL or ALGOL. No wait, all of those were new at
       some point...
     * gcc  3.0, a so-called "stable" release (released quite some time after Red Hat released gcc 2.96-RH),
       fixes  some  problems,  but  introduces  many  others  - for example, gcc 3.0.1 can't compile KDE 2.2
       correctly due to bugs in gcc 3.0.x's implementation in multiple inheritance in C++.
       With  the  recent  release  of gcc 3.1, there finally is a compiler that is better than 2.96 - but up
       until then (more than 18 months after the release of Red Hat Linux 7), gcc 2.96 was the best compiler
       available.

   Closing  with  a  list  of  commonly  found  constructs that gcc 2.96 doesn't compile (some of these code
   snippets are actually taken from "bug" reports), or compiles but generates unexpected results, along with
   why it's broken code and not a compiler problem, and how to fix it:

   Language Code Broken because... Correct code
   C++
main() {
        void *a;
        const void *b;
        a=b;
}

   Ignoring const qualifiers is valid (but not nice) C, but it's not valid C++.
main() {
        void *a;
        const void *b;
        a=(void*)b;
}

   C++
        int or=1;

   ISO C++ 98 defines or as ||, therefore compliant compilers parse the code as int ||=1;.
        int o_r=1;

   C++
int some_func() throw(someException);
int some_func()
{
}

   Function throws different exceptions than declared (declarations are commonly in header files, so this is
   usually not as easy to spot as it is here). This is as wrong as int some_func(int i);
   int some_func(char *i) { };.
int some_func() throw(someException);
int some_func() throw(someException)
{
}

   C++
template <class TYPE>
class a
{
        template<class TYPE>
        friend ostream &operator <<(ostream &os, a<TYPE> &b);
};

   According  to  the C++ standard: A template parameter shall not be redeclared within its scope (including
   nested scopes).
template <class TYPE>
class a
{
        template<class T>
        friend ostream &operator <<(ostream &os, a<T> &b);
};

   C++
main()
{
        exit(0);
}

   C++ forbids using functions that don't have a prototype.
#include <stdlib.h>
main()
{
        exit(0);
}

   C++
#if !defined(xor)
#define xor ^^
#endif

   ISO  C++  98  defines  xor as ^^, therefore compliant compilers parse the code as #if !defined(^^) [...].
   Don't  use  xor. ^^ is supported by both older and newer compilers, and checking for a compliant compiler
   with defined(xor) may work for some compilers, but is definitely not required by the standard.
   C++
class a {
private:
        enum aaa { TEST, TEST1, TEST2 };
        void xyz(aaa x);
};
class b {
        void xyz(a::aaa x);
};

   The definition of enum a is private to class a, so class b can't use it.
class a {
public:
        enum aaa { TEST, TEST1, TEST2 };
private:
        void xyz(aaa x);
};
class b {
        void xyz(a::aaa x);
};

   C
num = va_arg(args, short);


   Parameters passed to "..." type varargs are automatically promoted to int according to ISO C99.
num = (short)va_arg(args, int);
or plain
num = va_arg(args, int);

   C
int i;
*(float *)&i = 2.0;
return i;


   This  is  not  supposed  to work - older gcc versions could deal with it because they were not optimizing
   well. Don't do this.
   Quick fix: compile with -fno-strict-aliasing
   C
struct a {
        int a;
        int b;
};
[...]
struct a *s=(struct a *)malloc(sizeof(struct a));
memset(s + sizeof(int), 0, sizeof(int));
assert(s.b==0);


   The  compiler is free to add arbitrary padding in structs. There is no guarantee whatsoever that s.b will
   be stored at &(s.a)+sizeof(int). fix the code - how to do this should be fairly obvious.
   C++
template <class X> void *A<class X>::operator new(int a) { }


   Not valid ISO C++
template <class X> void *A<X>::operator new(int a) { }

   C++
class A {
public:
        typedef int a;
};
class B;
template <class A>
class C {
        typedef A b;
public:
        void c() { C<B>::b::a i; };
};


   A template and its instantation are not the same class according to ISO C++ 98.
class A {
public:
        typedef int a;
};
class B;
template <class A>
class C {
public:
        typedef A b;
        void c() { C<B>::b::a i; };
};

   C/Assembler
asm( [...]
"packuswb %%mm0, %%mm0 # B6 B4 B2 B0 | B6 B4 B2 B0\n\t"
"packuswb %%mm1, %%mm1 # R6 R4 R2 R0 | R6 R4 R2 R0\n\t"
"packuswb %%mm2, %%mm2 # G6 G4 G2 G0 | G6 G4 G2 G0\n\t"
[...]
)


   While  this  is  not  exactly  commonly found code, it's one of the perceived gcc 2.96 "bugs" most talked
   about.
   This  code used to be in MPlayer, causing it to miscompile, and its maintainers to add loud and blatantly
   wrong statements to their documentation.
   The  reason  this code miscompiles (only the packuswb %%mm0, %mm0 instruction is executed) is that recent
   versions of gcc, starting with 2.96, support both the Intel and AT&T variants of x86 assembly.
   The  pipe character is an actual symbol in the Intel variant, therefore its use in asm() constructs (even
   comments in asm constructs) is illegal.
   This  has  since  been  fixed  in  the  MPlayer  code - unfortunately its maintainers didn't remove their
   unjustified comments about gcc 2.96 at the same time.
asm( [...]
"packuswb %%mm0, %%mm0 # B6 B4 B2 B0  B6 B4 B2 B0\n\t"
"packuswb %%mm1, %%mm1 # R6 R4 R2 R0  R6 R4 R2 R0\n\t"
"packuswb %%mm2, %%mm2 # G6 G4 G2 G0  G6 G4 G2 G0\n\t"
[...]
)

   Feel free to send additions to the code list and any other comments to bero@bero.org.
   If you think you have found a real problem in gcc 2.96, report it at bugzilla and it will be fixed.

       

Back to Top Page
[legal] [ no spam policy ] [ Copyright] © 2008 Owl River Company
All rights reserved.

Last modified: Thu, 26 Sep 2002 09:58:49 -0400
http://www.owlriver.com/tips/gcc-296-bero/index.php