viuser
viuser

Reputation: 965

When is `extern` unavoidable for variables in C?

Answers to the question above don't answer my question. I know what extern does. The question is if we ever need extern. It only seems cleaner to use extern (and compile with -fno-common), but it doesn't seem there are situations when we need it.

Similar questions have already been answered (e.g. here), but this question is a bit different.

Say, I have two files:

file_a.c:

#include <stdio.h>

int sixsixsix = 666;

void lucky_seven();

int main(int argc, char *argv[]){
  printf("%d\n", sixsixsix);
  lucky_seven();
  printf("%d\n", sixsixsix);
  return 0;
}

file_b.c:

int sixsixsix;

void lucky_seven(){
  sixsixsix = 777;
}

I can compile with GCC using gcc -std=c99 file_a.c file_b.c with no errors. The compiled program gives as expected the output:

666
777

I only get errors if I compile with -fno-common. In this case it is necessary to use extern in file_b.c:

file_b.c:

extern int sixsixsix;

void lucky_seven(){
  sixsixsix = 777;
}

Aside from this special case, that is, if I have a compiler which doesn't put multiply declared variables in a common block, is there any other use for extern for variables? Can you give me example code in which extern becomes unavoidable?

Upvotes: 3

Views: 214

Answers (1)

terence hill
terence hill

Reputation: 3454

The extern keywords is necessary when your project consist of multiple files and a variable defined in one of the source file is needed in another one.

For example, if you define the variable in source1.c, then you must declare it as extern in source2.c (directly or by including an header file).

Any other file that reference the variable must declare it as extern.

See this post1 for a very very detailed explanation of the use of the extern keyword


EDIT

I was curious and thus continued to search on this topic.

This is the another relevant post2 which is directly addressing your question. And again the answer comes from Jonathan Leaffler.

Here, for sake of completeness, I will report an excerpt of the above question/answer.

The problem raised in the post was specifically: why if you define a variable in two distinct source files the compiler doesn't even rise a warning?

Short answer is that you do not violate any constrain in the Standard and the compiler is free to decide what to do.

Moreover, as shown in post1, it is possible to write a code that actually works, using gcc and clang (and maybe other compilers too).

But why we should bother? We know that is better to use extern! I found very interesting the observation of the OP in post2:

Note: this is important because the question occurs in the context of static analysis. If the two files may refuse to be linked on some platform, the analyzer should complain, but if every compilation platform accepts it then there is no reason to warn about it.


The relevant paragraph of the C standard is:

J.5.11 Multiple external definitions

There may be more than one external definition for the identifier of an object, with or without the explicit use of the keyword extern; if the definitions disagree, or more than one is initialized, the behavior is undefined (6.9.2).

This means that the result is Undefined Behaviour (see also the comment to the post). And, as Jonathan Leffler said:

One of the things that can happen is that the program behaves as you expect; and J.5.11 says, approximately, "you might be lucky more often than you deserve"

Confirmed in the comment by Johannes Schaub:

To be really clear whether it's allowed or not: No it's undefined behavior in C. It's like doing a[10] = 0; even if a is a int a1;


Conclusion

Defining a variable in multiple files is Undefined Behaviour, don't do that unless you are doing some wired test. Use extern!

Upvotes: 2

Related Questions