The GCC 10 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 to support new standards, or relaxed in standards-conforming ways to facilitate compilation or run-time performance.
Some of these changes are user visible and can cause grief when porting to GCC 10. This document is an effort to identify common issues and provide solutions. Let us know if you have suggestions for improvements!
-fno-common
A common mistake in C is omitting extern
when declaring a global
variable in a header file. If the header is included by several files it
results in multiple definitions of the same variable. In previous GCC
versions this error is ignored. GCC 10 defaults to -fno-common
,
which means a linker error will now be reported.
To fix this, use extern
in header files when declaring global
variables, and ensure each global is defined in exactly one C file.
If tentative definitions of particular variables need to be
placed in a common block, __attribute__((__common__))
can be
used to force that behavior even in code compiled without
-fcommon
.
As a workaround, legacy C code where all tentative definitions should
be placed into a common block can be compiled with -fcommon
.
int x; // tentative definition - avoid in header files
extern int y; // correct declaration in a header file
Some C++ Standard Library headers have been changed to no longer include
the <stdexcept>
header.
As such, C++ programs that used components defined in
<stdexcept>
or <string>
without
explicitly including the right headers will no longer compile.
Previously components such as std::runtime_error
,
std::string
and std::allocator
were implicitly defined after including unrelated headers such as
<array>
and <optional>
.
Correct code should include the appropriate headers for the classes being used.
GCC 10 now rejects argument mismatches occurring in the same source file.
Those are not permitted by the Fortran standard and in general have the
potential to generate invalid code. However, the Fortran standard does permit
passing an array element or a scalar string (of default character kind or of
c_char
kind) as actual argument to an array dummy argument.
(For the exact wording, see the Fortran standard on argument association;
in particular, Fortran 2018, Sect. 15.5.2.4, Para. 4.)
Depending on their nature, argument mismatches have the potential to cause the generation of invalid code and, hence, should be investigated. The most common reason that code fails due to newly enforced check is the following: instead of using an array element as actual argument, a scalar is used; one solution is to replace the scalar by a size-one array. (This should be passed as a whole as there is no point in passing it as array element.) Additionally, check that the code indeed only accesses this single element. — Other mismatches occur more rarely but usually indicate more serious bugs where a wrong result is likely (at least for some target-platform and optimization combination).
If short-term fixing of those issues is not feasible, the compiler flag
-fallow-argument-mismatch
(implied by -std=legacy
)
downgrades the error to a warning.
Example: Assume a subroutine which takes an assumed-size or explicit-size array and the array size as another argument, such as
subroutine sub_assumed(array, n)
real array(*)
integer n
…
end
subroutine another_explicit(array, n)
integer n
real array(n)
…
end
An invalid but comparably common use is to pass scalar to such procedures:
real var
…
call sub_assumed(var, 1)
This can be fixed in several ways. The simplest and most localized one is the following; the scalar is replaced by an array. In the second subroutine, it is assumed that the argument is both read from and written to. In the third procedure, a single number is passed, which is assumed to be only accessed for reading. (Note: By adding the brackets, a Fortran 66 or 77 compiler can no longer compile it.)
subroutine caller()
real var(1)
…
call sub_assumed(var, 1)
end
subroutine caller_arg(var)
real var
real var2(1)
…
var2(1) = var
call sub_assumed(var2, 1)
var = var2(1)
end
subroutine caller_readonly(var)
…
! Before: var = func(42.0, 1)
var = func([42.0], 1)
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.