In case I have a variable that may be used in several sources - is it a good practice to declare it in a header? or is it better to declare it in a .c
file and use extern
in other files?

- 10,432
- 15
- 57
- 79
5 Answers
You should declare the variable in a header file:
extern int x;
and then define it in one C file:
int x;
In C, the difference between a definition and a declaration is that the definition reserves space for the variable, whereas the declaration merely introduces the variable into the symbol table (and will cause the linker to go looking for it when it comes to link time).

- 23,670
- 6
- 53
- 72
-
7**Both** are declarations! At file-scope, the second is not a (full) definition, but a _tentative definition_. – too honest for this site Oct 05 '16 at 12:49
-
@toohonestforthissite What is supposed to be the difference between the two types of definitions? And what do you mean by file-scope? – Balázs Börcsök May 03 '22 at 12:23
You should declare it as extern
in a header file, and define it in exactly 1 .c file.
Note that the .c file should also use the header and so the standard pattern looks like:
// file.h
extern int x; // declaration
// file.c
#include "file.h"
int x = 1; // definition and re-declaration
re-definition is an error but re-declaration is Ok and often necessary.

- 263,252
- 30
- 330
- 514
-
1Indeed it *should* always use the header, so that if the types get out of whack between the declaration and definition the compiler will tell you. – caf Jul 22 '09 at 14:21
-
If you declare it like
int x;
in a header file which is then included in multiple places, you'll end up with multiple instances of x (and potentially compile or link problems).
The correct way to approach this is to have the header file say
extern int x; /* declared in foo.c */
and then in foo.c you can say
int x; /* exported in foo.h */
THen you can include your header file in as many places as you like.

- 12,934
- 4
- 46
- 54
The key is to keep the declarations of the variable in the header file and source file the same.
I use this trick
------sample.c------
#define sample_c
#include sample.h
(rest of sample .c)
------sample.h------
#ifdef sample_c
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int x;
Sample.c is only compiled once and it defines the variables. Any file that includes sample.h is only given the "extern" of the variable; it does allocate space for that variable.
When you change the type of x, it will change for everybody. You won't need to remember to change it in the source file and the header file.

- 12,390
- 20
- 65
- 92
-
3How do you deal with initialisation? - extern int x = 6; would give a warning on most compilers. – Dipstick Jul 22 '09 at 22:07
-
@chrisharris - that is a limitation. I usually have an Init() in each module to initialize variables. – Robert Deml Jul 23 '09 at 13:12
-
Don't you find it less cumbersome to have extern declaration in the header and definition in the C file? As @caf commented, if the types don't match you get a warning (I do always include the header file in the corresponding c file anyway, since I require all functions to have a prototype). – Gauthier Oct 08 '13 at 13:55
What about this solution?
#ifndef VERSION_H
#define VERSION_H
static const char SVER[] = "14.2.1";
static const char AVER[] = "1.1.0.0";
#else
extern static const char SVER[];
extern static const char AVER[];
#endif /*VERSION_H */
The only draw back I see is that the include guard doesn't save you if you include it twice in the same file.

- 121
- 1
- 1
- 7
-
41) The #ifndef guard prevents multiple definitions in a *single* source file (thus the extern definitions do nothing). 2) Declaring a static variable in a header means that each source file that includes it will have its own version of that variable rather than a single shared variable. Technically this will link, but behavior may not be desired (may not notice as you used const variables in this example, but use it for something non-const and you'll see it matters). Accepted answer is almost always the appropriate solution. – Assimilater May 31 '16 at 16:25