|
 |
|
Owl River Company
|
|
|
|
Your IP is: 3.233.239.20
|
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
Last modified: Thu, 26 Sep 2002 09:58:49 -0400
http://www.owlriver.com/tips/gcc-296-bero/index.php