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>();
ant
The 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
Copyright (C) Free Software Foundation, Inc. Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.
These pages are maintained by the GCC team. Last modified 2022-10-29.