15

Here's the deal. I've had two identical global variables in two different .c files, they weren't declared as extern. So each .c file should have seen its own variable, right?

But I have gotten some really strange behaviour, as if one file was reading the other files variable (after linking them together). Adding 'static' qualifier to both variables definitions seemed to fix this issue.

So what I'm actually wondering is, what exactly happened there without the 'static' qualifier?

cnicutar
  • 178,505
  • 25
  • 365
  • 392
Ivan Š
  • 1,024
  • 2
  • 10
  • 15
  • 1
    See also http://stackoverflow.com/questions/1490693/tentative-definitions-in-c99-and-linking for tricky aspects of extern linkage. – Pascal Cuoq Aug 25 '11 at 18:15
  • @Pascal Your answer is actually the most complete, too bad I can't flag it as the accepted one. I thought of myself doing something similar to what you did there with `nm'. Only thing that comes to my mind about this situation is that it is a major flaw in the standard, it's even talked about here http://www.jetcafe.org/jim/c-style.html#need_extern . I mean, who in the hell thought it would be nice if the compiler assumed 'extern' qualifier?? C++ sure as hell doesnt make such stupid assumption. – Ivan Š Aug 27 '11 at 11:44
  • 1
    Have been programming C for 25+ years. Never used "static" this way. LOL. But it solved my problem today! Thank you! – Paul Aug 18 '19 at 17:52

4 Answers4

27

So each .c file should have seen its own variable, right?

Wrong. In C, omitting static from a declaration means implicit extern linkage.

From C In a Nutshell:

The compiler treats function declarations without a storage class specifier as if they included the specifier extern. Similarly, any object identifiers that you declare outside all functions and without a storage class specifier have external linkage.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • Thanks, I did not know that. Why didn't the compiler raise an error or a warning tho? – Ivan Š Aug 25 '11 at 12:09
  • 3
    Just for reference, both Visual Studio 2008 and GCC 4.3.5 do follow this rule. And recompiling the code with c++ compiler (by changing to .cpp extension in VC, or calling g++ under linux) gives the "multiple definition" linking error. – Zac Feb 12 '13 at 16:08
4

ALWAYS initialize global variable, then compiler will not consider its linkage automatically as extern. Compiler will throw error during compilation.

This will help to avoid random problems in big code base ,because our code may use somebody else declared variable that has some random value (in our logic perspective)

Abraham
  • 41
  • 2
2

output file is generated by making object file of individually file and then linking them together by linker. Now when you have identical variable in two different file then individual file will compile with no error but at time of linking linker will get two definition of variable and generate an error. But In the case of static scope of both variable limited for the file so, every things works fine. I hope you will find this useful.

1

As far as I know, when you do not specify neither static nor extern then it's up to the compiler to choose. And gcc in this case goes for extern, thus you have to specify static in your case.

I had the same problem, a few years ago :-)

Ottavio Campana
  • 4,088
  • 5
  • 31
  • 58