Suppose there are two source files, file_1.c
and file_2.c
, which include the same header file file.h
. file.h
has a variable int var
. Once file_1.c
and file_2.c
include file.h
, do file_1.c
and file_2.c
have separate copies of the variable var
, or do they share the same?

- 730,956
- 141
- 904
- 1,278
-
1I think this will help [extern variables and mutiple definitions](https://stackoverflow.com/questions/64781854/why-are-function-definitions-implicitly-external-in-c/64782024#64782024) – csavvy Nov 15 '20 at 05:50
-
It depends — on whether the header contains `int var;` or `extern int var;`, and on which version of which compiler you use. With GCC 10.x or later, using `int var;` in the header by default gives you two variables — and prevents you from linking `file_1.o` and `file_2.o`. This is what the C standard expects, strictly. It does, however, mention a 'common extension' (which is a double entendre; it both emulates Fortran COMMON blocks, and is also a widely implemented extension) that allows linking with earlier versions of GCC. Using `extern int var;` in headers is always safest. – Jonathan Leffler Nov 15 '20 at 05:56
-
1See also [How do I use `extern` to share variables between source files](https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files) – Jonathan Leffler Nov 15 '20 at 05:58
-
not sure,it is allowed to say like this, but if that answer helped you, its good to give an up vote there !! – csavvy Nov 15 '20 at 06:06
-
@JonathanLeffler: Re “This is what the C standard expects, strictly”: Strictly, there is no expectation, as the C standard states it does not define the behavior. – Eric Postpischil Nov 15 '20 at 11:54
-
2It has been considered poor practice since at least the late 80's to define variables in a header file, so the question is: why are you doing this at al? Don't worry about the details of practices that should simply be avoided. – William Pursell Nov 15 '20 at 12:31
-
1See [How do I use `extern` to share variables between source files?](https://stackoverflow.com/q/1433204/15168) – Jonathan Leffler Jul 25 '22 at 02:28
1 Answers
Let’s start with a case that is fully defined by the C standard. If file.h
contains extern int x;
, it declares an identifier x
to refer to some int
object. This declaration is a part of each of file_1.c
and file_2.c
during compilation, and it is “made to refer to the same object” by linkage, per C 2018 6.2.2.
In this case, extern int x;
is merely a declaration that does not define x
. Some other declaration must define x
. This could be done by putting int x;
or int x = value;
in file_1.c
or file_2.c
. Then the answer to your question would be that extern int x;
in multiple source files would refer to the same object.
In the case you ask about, with int x;
in file.h
, the behavior is not fully defined by the C standard. Per C 2018 6.9.2, this is a tentative definition. If there is no regular definition of x
, the C standard says the tentative definition results in x
being defined as if it were initialized to zero. (In contrast, a declaration with an initializers, such as int x = 0;
, is a regular definition, not a tentative definition.)
In that case, both file_1.c
and file_2.c
define x
. So each file has its own definition. Then the C standard does not define the behavior, per 6.9 5, which says there shall be no more than one definition for such an identifier (and exactly one if it is actually used in an expression).
Since the C standard does not define the behavior, C implementations may. Until recently, GCC, Clang, and Unix tools treated tentative definitions differently from regular definitions. Multiple tentative definitions were allowed, and they were coalesced to form one definition. So, the answer to your question in this case is mixed: when int x;
appears in multiple source files, it nominally refers to “different” objects in some interpretation of the C standard during compilation, but linking resolves it to the same object.
Recent versions of GCC changed this behavior. By default, tentative definitions are treated more like regular definitions, so multiple tentative definitions will result in a link error. In this case, the answer to your question is that when int x;
appears in multiple source files, it refers to different objects, and this prevents the program from linking.

- 730,956
- 141
- 904
- 1,278

- 195,579
- 13
- 168
- 312
-
1Since [§6.9 ¶5](https://port70.net/~nsz/c/c11/n1570.html#6.9p5) says "… somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one", and since both `file_1.c` and `file_2.c` contain a definition of the object, I don't see how the standard allows you to link the two object files generated from the two source files into a single program ‚ other than via the [§J.5.11](https://port70.net/~nsz/c/c11/n1570.html#J.5.11) non-standard but common extension. – Jonathan Leffler Jul 25 '22 at 02:39
-
@JonathanLeffler: Yes, so? You do not see any way the standard allows this other than the way the standard allows this? What is the problem? – Eric Postpischil Jul 25 '22 at 11:29
-
@JonathanLeffler: In more detail, since the “shall” rule in 6.9 5 is violated, but 6.9 5 is not a constraints paragraph, then 4 2 applies: “the behavior is undefined”, and 5.1.1.3 1 tells us a diagnostic is not required. That means the C standard does not define the behavior, meaning the standard imposes no requirements. That means a conforming behavior is to link the two object modules successfully with no diagnostic; that behavior satisfies the C standard’s complete lack of requirements. – Eric Postpischil Jul 25 '22 at 11:35
-
@JonathanLeffler: In case the “shall” is bothering you, note that all the “shall” and “shall not” rules exist for the purpose of interpreting programs. They are notional statements about how programs are interpreted. They are not commands to human beings that they shall or shall not perform certain acts. Regardless of any rules in the C standard, humans may write programs with multiple external definitions of an identifier. Then the “shall” and “shall not” rules do not tell us the human has been bad or their program is “invalid.” They merely tell us the C standard does not define the behavior. – Eric Postpischil Jul 25 '22 at 11:44