1

When trying to compile and link two c modules with GCC, both containing a global variable with the same name, I get an error of multiple definitions. Despite the fact that both are so-called weak symbols.

A code example:
I've tried to compile and link the 2 following c modules:

// b1.c
int x;
int main() {}
// b2.c
int x;

Now, supposedly, the var x in both files, should be a weak symbol. So when linking, both should reference the same value.

But, for some reason, I get the following error:

$ gcc b1.c b2.c 
/usr/bin/ld: /tmp/ccCP4DM3.o:(.bss+0x0): multiple definition of `x`; /tmp/ccN4Bd4O.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status

$ gcc --version
gcc 11.3.0
$ ld --version
GNU ld 2.38

So, did something change? Because according to the "Computer Systems A Programmer’s Perspective" section 7.6, it should compile and link just fine using gcc without any special flags.

Tom
  • 11
  • 2
  • According to [this old answer](https://stackoverflow.com/a/3692077/440558), global uninitialized variables aren't defined as weak symbols, but rather treated as "common" symbols. But that answer is rather old now, so behavior might have changed to make such variables *not* common, leading to your error. – Some programmer dude Jan 11 '23 at 09:05
  • And which edition of the book are you reading? The last (third) edition was published in 2015 which is also quite a long time ago. – Some programmer dude Jan 11 '23 at 09:08
  • @Someprogrammerdude I'm reading the third edition. 2015 is indeed quite a long time ago, that's why I'm asking what's changed since then in terms of the linking process. – Tom Jan 11 '23 at 09:15
  • Using global variables is bad practice to begin with and the book should tell you as much. In the rare case where a programmer feverishly insists on using bad practices, then there should only be a single `int x;` in one .c file and a `extern int x;` in a .h file. – Lundin Jan 11 '23 at 09:52
  • 2
    You need to use the gcc `-fcommon` option. GCC 9 and earlier's `gcc` defaulted to using `-fcommon`. In GCC 10 and later, `gcc` defaulted to using `-fno-common`. – Ian Abbott Jan 11 '23 at 10:51
  • Thank you @IanAbbott ! Exactly the answer I was looking for. – Tom Jan 11 '23 at 11:15
  • But you should really only be using `-fcommon` when needed for compatibility with some old code, not for new code. – Ian Abbott Jan 11 '23 at 11:19

0 Answers0