The GCC 4.8 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.8. 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.
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
-Wmaybe-uninitialized.
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 add -Wno-maybe-uninitialized.
Improvements to the GCC infrastructure allow improvements in the ability of the optimizers to transform loops. Some loops that previously invoked undefined behavior may now be turned into endless loops.
For example,
unsigned int foo()
{
unsigned int data_data[128];
for (int fd = 0; fd < 128; ++fd)
data_data[fd] = fd * (0x02000001); // error
return data_data[0];
}
When fd is 64 or above, fd * 0x02000001 overflows, which is invalid in C/C++ for signed ints.
To fix, use the appropriate casts when converting between signed and unsigned types to avoid overflows. Like so:
data_data[fd] = (uint32_t) fd * (0x02000001U); // ok
The behavior of -Wall has changed and now includes the
new warning flag -Wsizeof-pointer-memaccess. This may
result in new warnings in code that compiled cleanly with previous
versions of GCC.
For example,
#include <string.h>
struct A { };
int main(void)
{
A obj;
A* p1 = &obj;
A p2[10];
memset(p1, 0, sizeof(p1)); // error
memset(p1, 0, sizeof(*p1)); // ok, dereferenced
memset(p2, 0, sizeof(p2)); // ok, array
return 0;
}
Gives the following diagnostic:
warning: argument to ‘sizeof’ in ‘void* memset(void*, int, size_t)’ call is the same expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess]
memset(p1, 0, sizeof(p1)); // error
^
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.
To fix, either re-write to use memcpy or dereference the last argument in the offending memset call.
As a workaround, use
-Wno-sizeof-pointer-memaccess.
The GCC pre-processor may now pre-includes a file that defines certain macros for the entirety of the translation unit. This allows fully conformant implementations of C99/C11 and other standards that require compiler or compiler + runtime macros that describe implementation availability.
On linux, <stdc-predef.h> is pre-included.
This subtle change means that some more creative uses of the pre-processor may now fail, with the following diagnostic:
/usr/include/stdc-predef.h:0: error: Syntax error near '3'
As a workaround, the stdc-predef.h preinclude can be disabled with
the use of -ffreestanding. For non C/C++ code, use the pre-processor flag -P.
The behavior of -Wall has changed and now includes the
new warning flag -Wunused-local-typedefs. This may
result in new warnings in code that compiled cleanly with previous
versions of GCC.
For example,
template<typename _Tp>
int
foo(_Tp __a)
{
typedef int return_type;
return 5;
}
int i = foo(415);
Gives the following diagnostic:
warning: typedef ‘return_type’ locally defined but not used [-Wunused-local-typedefs]
typedef int return_type;
^
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.
To fix, simply remove the unused typedef.
As a workaround, use
-Wno-unused-local-typedefs.
GCC by default no longer accepts code such as
struct A { struct B *C,; };
This example now gives the following diagnostic:
error: stray ‘,’ at end of member declaration
struct A { struct B *C,; };
^
To fix, simply remove the unused comma.
Jakub Jelinek, Results of a test mass rebuild of rawhide/x86_64 with gcc-4.8.0-0.1.fc19
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 2013-03-14.