The GCC 4.3 release series differs from previous GCC releases in more than the usual list of new features. Some of these changes are a result of bug fixing, and some old behaviors have been intentionally changed in order to support new standards, or relaxed in standards-conforming ways to facilitate compilation or runtime performance. Some of these changes are not visible to the naked eye, and will not cause problems when updating from older GCC versions.
However, some of these changes are visible, and can cause grief to users porting to GCC 4.3. This document is an effort to identify major issues and provide clear solutions in a quick and easily-searched manner. Additions and suggestions for improvement are welcome.
When compiling with -std=c99 or -std=gnu99,
the extern inline keywords changes meaning. GCC 4.3
conforms to the ISO C99 specification, where extern
inline is very different thing than the GNU extern
inline extension. For the following code compiled
with -std=c99,
extern inline int
foo()
{ return 5; }
Will result in a function definition for foo being
emitted in the subsequent object file, whereas previously there was none. As a
result, files that use this extension and compile in the C99 dialect
will see many errors of the form:
multiple definition of `foo' first defined here
When linking together multiple object files.
If the old GNU extern inline behavior is desired, one can
use extern inline __attribute__((__gnu_inline__)). The
use of this attribute can be guarded by #ifdef
__GNUC_STDC_INLINE__ which is a macro which is defined when
inline has the ISO C99 behavior. Alternatively the code can be compiled
with the -fgnu89-inline option.
The resulting, changed code looks like:
extern inline __attribute__((__gnu_inline__)) int
foo()
{ return 5; }
Significant changes were made to -Wconversion. In
addition, improvements to the GCC infrastructure allow improvements in
the ability of several existing warnings to spot problematic code. As
such, new warnings may exist for previously warning-free code that
uses
-Wuninitialized, -Wstrict-aliasing , -Wunused-function, -Wunused-variable. Note
that -Wall subsumes many of these warning flags.
Although these warnings will
not result in compilation failure, often -Wall is used in
conjunction with -Werror and as a result, new warnings
are turned into new errors.
As a workaround, remove -Werror until the new warnings
are fixed, or for conversion warnings add -Wno-conversion.
As detailed
here (Header dependency streamlining), many of the standard C++ library
include files have been edited to only include the smallest
possible number of additional files. As such, many C++ programs that
used std::memcpy without including <cstring>, or
used std::auto_ptr without including <memory> will
no longer compile.
Usually, this error is of the form:
error: 'strcmp' was not declared in this scope
The table below shows some of the missing items, and the header file that will have to be added as an #include for the compile to succeed.
| If missing | Then include this header |
|---|---|
| find, for_each, sort | <algorithm> |
| ostream_iterator, istream_iterator | <iterator> |
| auto_ptr | <memory> |
| typeid | <typeinfo> |
| isalnum, toupper | <cctype> |
| INT_MIN, INT_MAX, RAND_MAX | <climits> |
| printf | <cstdio> |
| atoi, free, rand, exit | <cstdlib> |
| EXIT_FAILURE | <cstdlib> |
| strcmp, strdup, strcpy, memcpy | <cstring> |
Various backwards and deprecated headers have been removed.
| If missing | Then include this header |
|---|---|
| <algobase.h> | <algorithm> |
| <algo.h> | <algorithm> |
| <alloc.h> | <memory> |
| <bvector.h> | <vector> |
| <complex.h> | <complex> |
| <defalloc.h> | <memory> |
| <deque.h> | <deque> |
| <fstream.h> | <fstream> |
| <function.h> | <functional> |
| <hash_map.h> | <tr1/unordered_map> |
| <hashtable.h> | <tr1/unordered_map> or <tr1/unordered_set> |
| <heap.h> | <queue> |
| <iomanip.h> | <iomanip> |
| <iostream.h> | <iostream> |
| <istream.h> | <istream> |
| <iterator.h> | <iterator> |
| <list.h> | <list> |
| <map.h> | <map> |
| <multimap.h> | <map> |
| <multiset.h> | <set> |
| <new.h> | <new> |
| <ostream.h> | <ostream> |
| <pair.h> | <utility> |
| <queue.h> | <queue> |
| <rope.h> | <ext/rope> |
| <set.h> | <set> |
| <slist.h> | <ext/slist> |
| <stack.h> | <stack> |
| <streambuf.h> | <streambuf> |
| <stream.h> | <iostream> |
| <tempbuf.h> | <ext/memory> |
| <tree.h> | <ext/rb_tree> or <ext/pb_ds/assoc_container.hpp> |
| <vector.h> | <vector> |
For future reference, available headers are listed in the libstdc++ manual.
An example.
#include <iostream.h>
int main()
{
cout << "I'm too old" << endl;
return 0;
}
Compiling with previous compilers gives:
warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
But now says:
error: iostream.h: No such file or directory In function 'int main()': 6: error: 'cout' was not declared in this scope 6: error: 'endl' was not declared in this scope
Fixing this is easy, as demonstrated below.
#include <iostream>
using namespace std;
int main()
{
cout << "I work again" << endl;
return 0;
}
Note that explicitly qualifying cout as std::cout and likewise for endl instead of globally injecting the std namespace (ie, using namespace std) will also work.
GCC by default no longer accepts code such as
template <class _Tp> class auto_ptr {};
template <class _Tp>
struct counted_ptr
{
auto_ptr<_Tp> auto_ptr();
};
but will issue the diagnostic
error: declaration of 'auto_ptr<_Tp> counted_ptr<_Tp>::auto_ptr()' error: changes meaning of 'auto_ptr' from 'class auto_ptr<_Tp>'
The reference to struct auto_ptr needs to be qualified
here, or the name of the member function changed to be unambiguous.
template <class _Tp> class auto_ptr {};
template <class _Tp>
struct counted_ptr
{
::auto_ptr<_Tp> auto_ptr();
};
In addition, -fpermissive can be used as a temporary
workaround to convert the error into a warning until the code is
fixed. Note that then in some case name lookup will not be standard
conforming.
Duplicate function parameters are now treated uniformly as an error in C and C++.
void foo(int w, int w);
Now gives the following, re-worded error for both C and C++:
error: multiple parameters named 'w'
To fix, rename one of the parameters something unique.
void foo(int w, int w2);
The two-argument signature for main has int as the
first argument. GCC 4.3 rigorously enforces this.
int main(unsigned int m, char** c)
{ return 0; }
Gives:
error: first argument of 'int main(unsigned int, char**)' should be 'int'
Fixing this is straightforward: change the first argument to be of
type int, not unsigned int. As transformed:
int main(int m, char** c)
{ return 0; }
Specializations of templates cannot explicitly specify a storage class, and have the same storage as the primary template. This is a change from previous behavior, based on the feedback and commentary as part of the ISO C++ Core Defect Report 605.
template<typename T> static void foo(); template<> static void foo<void>();
Gives:
error: explicit template specialization cannot have a storage class
This also happens with the extern specifier. Fixing
this is easy: just remove any storage specifier on the specialization. Like so:
template<typename T> static void foo(); template<> void foo<void>();
antThe use of the Eclipse Java compiler in GCC 4.3 enables the use of
all 1.5 language features, but use with older versions of
the ant build tool are problematic. Typical errors of
this sort look like:
[javac] source level should be comprised in between '1.3' and '1.6' (or '5', '5.0', ..., '7' or '7.0'): 1.2
To successfuly use the earlier java dialects with GCC, please use this patch:
svn diff -r529854:529855 http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java
Jakub Jelinek, Mass rebuild status with gcc-4.3.0-0.4 of rawhide-20071220
Simon Baldwin, [PATCH][RFC] C++ error for parameter redefinition in function prototypes
Simon Baldwin, [REVISED PATCH][RFC] Fix PR c++/31923: Storage class with explicit template specialization