Gcc 10 porting notes/fno common

From Gentoo Wiki
Jump to: navigation, search

Overview

gcc-10 and above flipped a default from -fcommon to -fno-common.

This changed gcc code generator to emit globals without explicit initializer from .bss (via COMMON symbol type) to .data (via DEFAULT symbol type).

Example

The problem

GCC will reject multiple definition of global variables starting from gcc-10:

//a.c
int a = 42;

// main.c
int a;
int main(){}


user $gcc a.c main.c -o main
ld: a.o:(.bss+0x0): multiple definition of `a'; main.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status

The fix (source changes, preferred)

The fix is simple: explicitly mark declarations as such and avoid multiple definitions:

//a.c
int a = 42;

// main.c
extern int a; // was 'int a;'
int main(){}

The -fcommon workaround (discouraged)

If the problem is not that easy to fix or you are afraid it can break the program you then can report a bug upstream to make the decision on a correct fix.

As a local workaround you can revert back to old behaviour:

src_configure() {
  # discouraged, source change fix is preferred
  append-cflags -fcommon # https://link/to/upstream/bug/report
  econf ...
}

Reproducing the build failure with older gcc versions

To reproduce a build failure on older gcc use

CFLAGS="... -fno-common"

Links