GCC 3.4 Release Series — Changes, New Features, and Fixes - GNU Project GCC 3.4 Release SeriesChanges, New Features, and Fixes The final release in the 3.4 release series is GCC 3.4.6. The series is now closed. GCC 3.4 has many improvements in the C++ front end. Before reporting a bug, please make sure it's really GCC, and not your code, that is broken. Caveats GNU Make is now required to build GCC. With -nostdinc the preprocessor used to ignore both standard include paths and include paths contained in environment variables. It was neither documented nor intended that environment variable paths be ignored, so this has been corrected. GCC no longer accepts the options -fvolatile, -fvolatile-global and -fvolatile-static. It is unlikely that they worked correctly in any 3.x release. GCC no longer ships <varargs.h>. Use <stdarg.h> instead. Support for all the systems obsoleted in GCC 3.3 has been removed from GCC 3.4. See below for a list of systems which are obsoleted in this release. GCC now requires an ISO C90 (ANSI C89) C compiler to build. K&R C compilers will not work. The implementation of the MIPS ABIs has changed. As a result, the code generated for certain MIPS targets will not be binary compatible with earlier releases. In previous releases, the MIPS port had a fake "hilo" register with the user-visible name accum. This register has been removed. The implementation of the SPARC ABIs has changed. As a result, the code generated will not be binary compatible with earlier releases in certain cases. The configure option --enable-threads=pthreads has been removed; use --enable-threads=posix instead, which should have the same effect. Code size estimates used by inlining heuristics for C, Objective-C, C++ and Java have been redesigned significantly. As a result the parameters of -finline-insns, --param max-inline-insns-single and --param max-inline-insns-auto need to be reconsidered. --param max-inline-slope and --param min-inline-insns have been removed; they are not needed for the new bottom-up inlining heuristics. The new unit-at-a-time compilation scheme has several compatibility issues: The order in which functions, variables, and top-level asm statements are emitted may have changed. Code relying on some particular ordering needs to be updated. The majority of such top-level asm statements can be replaced by section attributes. Unreferenced static variables and functions are removed. This may result in undefined references when an asm statement refers to the variable/function directly. In that case either the variable/function shall be listed in asm statement operand or in the case of top-level asm statements the attribute used shall be used to force function/variable to be always output and considered as a possibly used by unknown code. For variables the attribute is accepted only by GCC 3.4 and newer, while for earlier versions it is sufficient to use unused to silence warnings about the variables not being referenced. To keep code portable across different GCC versions, you can use appropriate preprocessor conditionals. Static functions now can use non-standard passing conventions that may break asm statements calling functions directly. Again the attribute used shall be used to prevent this behavior. As a temporary workaround, -fno-unit-at-a-time can be used, but this scheme may not be supported by future releases of GCC. GCC 3.4 automatically places zero-initialized variables in the .bss section on some operating systems. Versions of GNU Emacs up to (and including) 21.3 will not work correctly when using this optimization; you can use -fno-zero-initialized-in-bss to disable it. If GCC 3.4 is configured with --enable-threads=posix (the default on most targets that support pthreads) then _REENTRANT will be defined unconditionally by some libstdc++ headers. C++ code which relies on that macro to detect whether multi-threaded code is being compiled might change in meaning, possibly resulting in linker errors for single-threaded programs. Affected users of Boost should compile single-threaded code with -DBOOST_DISABLE_THREADS. See Bugzilla for more information. General Optimizer Improvements Usability of the profile feedback and coverage testing has been improved. Performance of profiled programs has been improved by faster profile merging code. Better use of the profile feedback for optimization (loop unrolling and loop peeling). File locking support allowing fork() calls and parallel runs of profiled programs. Coverage file format has been redesigned. gcov coverage tool has been improved. make profiledbootstrap available to build a faster compiler. Experiments made on i386 hardware showed an 11% speedup on -O0 and a 7.5% speedup on -O2 compilation of a large C++ testcase. New value profiling pass enabled via -fprofile-values New value profile transformations pass enabled via -fvpt aims to optimize some code sequences by exploiting knowledge about value ranges or other properties of the operands. At the moment a conversion of expensive divisions into cheaper operations has been implemented. New -fprofile-generate and -fprofile-use command-line options to simplify the use of profile feedback. A new unit-at-a-time compilation scheme for C, Objective-C, C++ and Java which is enabled via -funit-at-a-time (and implied by -O2). In this scheme a whole file is parsed first and optimized later. The following basic inter-procedural optimizations are implemented: Removal of unreachable functions and variables Discovery of local functions (functions with static linkage whose address is never taken) On i386, these local functions use register parameter passing conventions. Reordering of functions in topological order of the call graph to enable better propagation of optimizing hints (such as the stack alignments needed by functions) in the back end. Call graph based out-of-order inlining heuristics which allows to limit overall compilation unit growth (--param inline-unit-growth). Overall, the unit-at-a-time scheme produces a 1.3% improvement for the SPECint2000 benchmark on the i386 architecture (AMD Athlon CPU). More realistic code size estimates used by inlining for C, Objective-C, C++ and Java. The growth of large functions can now be limited via --param large-function-insns and --param large-function-growth. A new cfg-level loop optimizer pass replaces the old loop unrolling pass and adds two other loop transformations -- loop peeling and loop unswitching -- and also uses the profile feedback to limit code growth. (The three optimizations are enabled by -funroll-loops, -fpeel-loops and -funswitch-loops flags, respectively). The old loop unroller still can be enabled by -fold-unroll-loops and may produce better code in some cases, especially when the webizer optimization pass is not run. A new web construction pass enabled via -fweb (and implied by -O3) improves the quality of register allocation, CSE, first scheduling pass and some other optimization passes by avoiding re-use of pseudo registers with non-overlapping live ranges. The pass almost always improves code quality but does make debugging difficult and thus is not enabled by default by -O2 The pass is especially effective as cleanup after code duplication passes, such as the loop unroller or the tracer. Experimental implementations of superblock or trace scheduling in the second scheduling pass can be enabled via -fsched2-use-superblocks and -fsched2-use-traces, respectively. New Languages and Language specific improvements Ada The Ada front end has been updated to include numerous bug fixes and enhancements. These include: Improved project file support Additional set of warnings about potential wrong code Improved error messages Improved code generation Improved cross reference information Improved inlining Better run-time check elimination Better error recovery More efficient implementation of unbounded strings Added features in GNAT.Sockets, GNAT.OS_Lib, GNAT.Debug_Pools, ... New GNAT.xxxx packages (e.g. GNAT.Strings, GNAT.Exception_Action) New pragmas New -gnatS switch replacing gnatpsta Implementation of new Ada features (in particular limited with, limited aggregates) C/Objective-C/C++ Precompiled headers are now supported. Precompiled headers can dramatically speed up compilation of some projects. There are some known defects in the current precompiled header implementation that will result in compiler crashes in relatively rare situations. Therefore, precompiled headers should be considered a "technology preview" in this release. Read the manual for details about how to use precompiled headers. File handling in the preprocessor has been rewritten. GCC no longer gets confused by symlinks and hardlinks, and now has a correct implementation of #import and #pragma once. These two directives have therefore been un-deprecated. The undocumented extension that allowed C programs to have a label at the end of a compound statement, which has been deprecated since GCC 3.0, has been removed. The cast-as-lvalue extension has been removed for C++ and deprecated for C and Objective-C. In particular, code like this: int i; (char) i = 5; or this: char *p; ((int *) p)++; is no longer accepted for C++ and will not be accepted for C and Objective-C in a future version. The conditional-expression-as-lvalue extension has been deprecated for C and Objective-C. In particular, code like this: int a, b, c; (a ? b : c) = 2; will not be accepted for C and Objective-C in a future version. The compound-expression-as-lvalue extension has been deprecated for C and Objective-C. In particular, code like this: int a, b; (a, b) = 2; will not be accepted for C and Objective-C in a future version. A possible non-intrusive workaround is the following: (*(a, &b)) = 2; Several built-in functions such as __builtin_popcount for counting bits, finding the highest and lowest bit in a word, and parity have been added. The -fwritable-strings option has been deprecated and will be removed. Many C math library functions are now recognized as built-ins and optimized. The C, C++, and Objective-C compilers can now handle source files written in any character encoding supported by the host C library. The default input character set is taken from the current locale, and may be overridden with the -finput-charset command line option. In the future we will add support for inline encoding markers. C++ G++ is now much closer to full conformance to the ISO/ANSI C++ standard. This means, among other things, that a lot of invalid constructs which used to be accepted in previous versions will now be rejected. It is very likely that existing C++ code will need to be fixed. This document lists some of the most common issues. A hand-written recursive-descent C++ parser has replaced the YACC-derived C++ parser from previous GCC releases. The new parser contains much improved infrastructure needed for better parsing of C++ source codes, handling of extensions, and clean separation (where possible) between proper semantics analysis and parsing. The new parser fixes many bugs that were found in the old parser. You must now use the typename and template keywords to disambiguate dependent names, as required by the C++ standard. struct K { typedef int mytype_t; }; template <class T1> struct A { template <class T2> struct B { void callme(void); }; template <int N> void bar(void) { // Use 'typename' to tell the parser that T1::mytype_t names // a type. This is needed because the name is dependent (in // this case, on template parameter T1). typename T1::mytype_t x; x = 0; } }; template <class T> void template_func(void) { // Use 'template' to prefix member templates within // dependent types (a has type A<T>, which depends on // the template parameter T). A<T> a; a.template bar<0>(); // Use 'template' to tell the parser that B is a nested // template class (dependent on template parameter T), and // 'typename' because the whole A<T>::B<int> is // the name of a type (again, dependent). typename A<T>::template B<int> b; b.callme(); } void non_template_func(void) { // Outside of any template class or function, no names can be // dependent, so the use of the keyword 'typename' and 'template' // is not needed (and actually forbidden). A<K> a; a.bar<0>(); A<K>::B<float> b; b.callme(); } In a template definition, unqualified names will no longer find members of a dependent base (as specified by [temp.dep]/3 in the C++ standard). For example, template <typename T> struct B { int m; int n; int f (); int g (); }; int n; int g (); template <typename T> struct C : B<T> { void h () { m = 0; // error f (); // error n = 0; // ::n is modified g (); // ::g is called } }; You must make the names dependent, e.g. by prefixing them with this->. Here is the corrected definition of C<T>::h, template <typename T> void C<T>::h () { this->m = 0; this->f (); this->n = 0 this->g (); } As an alternative solution (unfortunately not backwards compatible with GCC 3.3), you may use using declarations instead of this->: template <typename T> struct C : B<T> { using B<T>::m; using B<T>::f; using B<T>::n; using B<T>::g; void h () { m = 0; f (); n = 0; g (); } }; In templates, all non-dependent names are now looked up and bound at definition time (while parsing the code), instead of later when the template is instantiated. For instance: void foo(int); template <int> struct A { static void bar(void){ foo('a'); } }; void foo(char); int main() { A<0>::bar(); // Calls foo(int), used to call foo(char). } In an explicit instantiation of a class template, you must use class or struct before the template-id: template <int N> class A {}; template A<0>; // error, not accepted anymore template class A<0>; // OK The "named return value" and "implicit typename" extensions have been removed. Default arguments in function types have been deprecated and will be removed. ARM-style name-injection of friend declarations has been deprecated and will be removed. For example: struct S { friend void f(); }; void g() { f(); } will not be accepted by future versions of G++; instead a declaration of "f" will need to be present outside of the scope of "S". Covariant returns are implemented for all but varadic functions that require an adjustment. When -pedantic is used, G++ now issues errors about spurious semicolons. For example, namespace N {}; // Invalid semicolon. void f() {}; // Invalid semicolon. G++ no longer accepts attributes for a declarator after the initializer associated with that declarator. For example, X x(1) __attribute__((...)); is no longer accepted. Instead, use: X x __attribute__((...)) (1); Inside the scope of a template class, the name of the class itself can be treated as either a class or a template. So GCC used to accept the class name as argument of type template, and template template parameter. However this is not C++ standard compliant. Now the name is not treated as a valid template template argument unless you qualify the name by its scope. For example, the code below no longer compiles. template <template <class> class TT> class X {}; template <class T> class Y { X<Y> x; // Invalid, Y is always a type template parameter. }; The valid code for the above example is X< ::Y> x; // Valid. (Notice the space between < and : to prevent GCC to interpret this as a digraph for [.) Friend declarations that refer to template specializations are rejected if the template has not already been declared. For example, template <typename T> class C { friend void f<> (C&); }; is rejected. You must first declare f as a template, template <typename T> void f(T); In case of friend declarations, every name used in the friend declaration must be accessible at the point of that declaration. Previous versions of G++ used to be less strict about this and allowed friend declarations for private class members, for example. See the ISO C++ Standard Committee's defect report #209 for details. Declaration of member functions of class templates as friends are supported. For example, template <typename T> struct A { void f(); }; class C { template <typename T> friend void A<T>::f(); }; You must use template <> to introduce template specializations, as required by the standard. For example, template <typename T> struct S; struct S<int> { }; is rejected. You must write, template <> struct S<int> {}; G++ used to accept code like this, struct S { int h(); void f(int i = g()); int g(int i = h()); }; This behavior is not mandated by the standard. Now G++ issues an error about this code. To avoid the error, you must move the declaration of g before the declaration of f. The default arguments for g must be visible at the point where it is called. The C++ ABI Section 3.3.3 specifications for the array construction routines __cxa_vec_new2 and __cxa_vec_new3 were changed to return NULL when the allocator argument returns NULL. These changes are incorporated into the libstdc++ runtime library. Using a name introduced by a typedef in a friend declaration or in an explicit instantiation is now rejected, as specified by the ISO C++ standard. class A; typedef A B; class C { friend class B; // error, no typedef name here friend B; // error, friend always needs class/struct/enum friend class A; // OK }; template <int> class Q {}; typedef Q<0> R; template class R; // error, no typedef name here template class Q<0>; // OK When allocating an array with a new expression, GCC used to allow parentheses around the type name. This is actually ill-formed and it is now rejected: int* a = new (int)[10]; // error, not accepted anymore int* a = new int[10]; // OK When binding an rvalue of class type to a reference, the copy constructor of the class must be accessible. For instance, consider the following code: class A { public: A(); private: A(const A&); // private copy ctor }; A makeA(void); void foo(const A&); void bar(void) { foo(A()); // error, copy ctor is not accessible foo(makeA()); // error, copy ctor is not accessible A a1; foo(a1); // OK, a1 is a lvalue } This might be surprising at first sight, especially since most popular compilers do not correctly implement this rule (further details). When forming a pointer to member or a pointer to member function, access checks for class visibility (public, protected, private) are now performed using the qualifying scope of the name itself. This is better explained with an example: class A { public: void pub_func(); protected: void prot_func(); private: void priv_func(); }; class B : public A { public: void foo() { &A::pub_func; // OK, pub_func is accessible through A &A::prot_func; // error, cannot access prot_func through A &A::priv_func; // error, cannot access priv_func through A &B::pub_func; // OK, pub_func is accessible through B &B::prot_func; // OK, can access prot_func through B (within B) &B::priv_func; // error, cannot access priv_func through B } }; Runtime Library (libstdc++) Optimization work: Streamlined streambuf, filebuf, separate synched with C Standard I/O streambuf. All formatted I/O now uses cached locale information. STL optimizations (memory/speed for list, red-black trees as used by sets and maps). More use of GCC builtins. String optimizations (avoid contention on increment/decrement-and-test of the reference count in the empty-string object, constructor from input_iterators speedup). Static linkage size reductions. Large File Support (files larger than 2 GB on 32-bit systems). Wide character and variable encoding filebuf work (UTF-8, Unicode). Generic character traits. Also support wchar_t specializations on Mac OS 10.3.x, FreeBSD 5.x, Solaris 2.7 and above, AIX… truncated (43,020 more characters in archive)