The GCC 4.9 release series differs from previous GCC releases in a number of ways. 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 run-time 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.9. 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.
#pragma omp end
directive now diagnosedGCC no longer accepts invalid OpenMP like:
#pragma omp critical
foo ();
#pragma omp end critical
This example now gives the following diagnostic:
t.c:6:19: error: expected ‘declare’ before ‘critical’ #pragma omp end critical ^
There is no #pragma omp end critical
directive for C/C++
(whereas for Fortran there is !$omp end critical
) but before
OpenMP 4.0 support was added, this would be diagnosed only with
-Wunknown-pragmas
. As OpenMP 4.0 includes the
#pragma omp end declare target
directive, this is now a parsing
error.
GCC might now optimize away the null pointer check in code like:
int copy (int* dest, int* src, size_t nbytes) {
memmove (dest, src, nbytes);
if (src != NULL)
return *src;
return 0;
}
The pointers passed to memmove
(and similar functions in
<string.h>
) must be non-null even when
nbytes==0
, so GCC can use that information to remove the check
after the memmove
call. Calling copy(p, NULL, 0)
can therefore deference a null pointer and crash.
The example above needs to be fixed to avoid the invalid
memmove
call, for example:
if (nbytes != 0)
memmove (dest, src, nbytes);
This optimization can also affect implicit null pointer checks such as
the one done by the C++ runtime for the delete[]
operator.
GCC now warns about unused right-hand side of a comma expression that contains no side effects:
int i = 42;
bar (), i;
This example now gives the following diagnostic:
w.c:5:9: warning: right-hand operand of comma expression has no effect [-Wunused-value] bar (), i; ^
To suppress this warning cast the right-hand operand to void
:
int i = 42;
bar (), (void) i;
catch
handler now rejectedGCC by default no longer accepts code such as:
try {
// ...
} catch (const E& e) {
int e = 0;
}
This example now gives the following diagnostic:
e.cc:8:9: error: redeclaration of ‘int e’ [-fpermissive] int e = 0; ^ e.cc:7:21: note: ‘const E& e’ previously declared here } catch (const E& e) { ^
The standard says the example is ill-formed, so GCC was changed to reject it for PR31952. To fix the error either rename one of the variables or use an additional nested scope for the second one.
GCC by default no longer accepts code such as:
template<class T>
struct A
{
void f(int);
};
template<class T>
void A<T>::f(int i=0) { }
This example now gives the following diagnostic:
r.cc:8:21: error: redeclaration of ‘void A<T>::f(int)’ may not have default arguments [-fpermissive]
The standard says the example is ill-formed, so GCC was changed to reject it for PR54485. To fix the error the default argument must appear when the member function is first declared.
<memory>
changesThe contents of the <memory>
header were reorganized to
allow easier reuse within libstdc++.
As a result, some code which directly includes headers such as
<bits/shared_ptr.h>
will no longer compile and may produce
a diagnostic like:
/usr/include/c++/4.9.0/bits/shared_ptr_base.h: In member function ‘virtual void* std::_Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp>::_M_get_deleter(const std::type_info&)’: /usr/include/c++/4.9.0/bits/shared_ptr_base.h:479:39: error: must #include <typeinfo> before using typeid return __ti == typeid(_Deleter) ? &_M_impl._M_del() : nullptr; ^
All <bits/xxx.h>
headers are internal library headers
and including them directly is not supported and may be made into a hard
error in a future GCC release.
<cstddef>
changesThe <cstddef>
header was updated for C++11 support and
this breaks some libraries which misuse macros meant for internal use by GCC
only.
For instance with GMP versions up to 5.1.3, you may see:
/usr/include/c++/4.9.0/cstddef:51:11: error: ‘::max_align_t’ has not been declared using ::max_align_t; ^
Another possible error is:
someheader.h:99:13: error: ‘ptrdiff_t’ does not name a type
A workaround until libraries get updated is to include
<cstddef>
or <stddef.h>
before any
headers from that library.
GCC now checks return types more strictly and will reject declarations of functions which return abstract types, including in uninstantiated templates and in typedefs to function pointers. Returning an abstract type is not possible so the code must be fixed.
Matthias Klose, Debian test rebuild on x86_64-linux-gnu with trunk 20140118
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.