The GCC 4.7 release series differs from previous GCC releases in more than the usual list of changes. Some of these 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 versions.
However, some of these changes are visible, and can cause grief to users porting to GCC 4.7. 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.
Earlier releases did not warn or error about completely invalid options on gcc/g++/gfortran etc. command lines, if nothing was compiled, but only linking was performed. This is no longer the case. For example,
gcc -Wl -o foo foo.o -mflat_namespace
Now produces the following error
error: unrecognized command line option ‘-Wl’ error: unrecognized command line option ‘-mflat_namespace’
Invalid options need to be removed from the command line or replaced by something that is valid.
Many of the standard C++ library include files have been edited to no longer include <unistd.h> to remove namespace pollution.
As such, C++ programs that used functions
including truncate
, sleep
or pipe
without first including <unistd.h> will no
longer compile. The diagnostic produced is similar to:
error: ‘truncate’ was not declared in this scope
error: ‘sleep’ was not declared in this scope
error: ‘pipe’ was not declared in this scope
error: there are no arguments to 'offsetof' that depend on a template parameter, so a declaration of 'offsetof' must be available
Fixing this issue is easy: just include <unistd.h>.
At no time should user-level code use private
GCC-implementation-space macros such as
_GLIBCXX_HAS_GTHREADS
to determine concurrency support
at compile-time
Instead, use the POSIX macro _REENTRANT
.
The C++ compiler no longer performs some extra unqualified lookups it had performed in the past, namely dependent base class scope lookups and unqualified template function lookups.
C++ programs that depended on the compiler's previous behavior may no longer compile. For example, code such as
template<typename T> int t(T i) { return f(i); } int f(int i) { return i; } int main() { return t(1); }
Will result in the following diagnostic:
In instantiation of ‘int t(T) [with T = int]’ required from here error: ‘f’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] note: ‘int f(int)’ declared here, later in the translation unit
To fix, make sure the function f
in the code above is
declared before first use in function t
. Like so:
int f(int i) { return i; } template<typename T> int t(T i) { return f(i); } int main() { return t(1); }
This can be temporarily worked around by using -fpermissive
.
The C++ compiler no longer allows identical identifiers in some nested scopes. Namely:
void f(int); int main() { for (int i=0;;++i) { int i=5; f(i); } return 0; }
Now results in the error:
error: redeclaration of ‘int i’ error: ‘int i’ previously declared here
To fix this, rename one of the two variables from i
to a
distinct identifier.
The C++ compiler in ISO C++11 mode std={c++11,c++0x,gnu++11,gnu++0x}
supports user defined literals, which are incompatible with some valid
ISO C++03 code.
In particular, whitespace is now needed after a string literal and before something that could be a valid user defined literal. Take the valid ISO C++03 code
const char *p = "foobar"__TIME__;
In C++03, the __TIME__
macro expands to some string
literal and is concatenated with the other one. In
C++11 __TIME__
isn't expanded, instead operator
"" __TIME__
is being looked up, resulting in the
following diagnostic:
error: unable to find string literal operator ‘operator"" __TIME__’
This applies to any string literal followed without whitespace by some macro. To fix, just add some whitespace between the string literal and the macro name.
The ELF symbol visibility of a template instantiation is now properly
constrained by the visibility of its template arguments. As a result,
users that compile with -fvisibility=hidden
should be aware of
the visibility of types #include
d from library headers; if the
header does not explicitly control symbol visibility (as the standard C++
library does) types from those headers will be hidden, and so
instantiations that use those types as template arguments will also be
hidden. For instance,
#include <vector> // template std::vector has default visibility #include <ctime> // struct tm has hidden visibility template class std::vector<tm>; // instantiation has hidden visibility
Most likely only code that uses extern
explicit template
instantiation in headers will notice this change. One approach to
adjusting the visibility of a library header foo.h
is to
create a forwarding header on the -I
include path consisting of
#pragma GCC visibility push(default) #include_next <foo.h> #pragma GCC visibility push
Jakub Jelinek, GCC 4.7 related common package rebuild failures (was Re: mass rebuild status)
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-26.