Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should variable definition be in header files?

My very basic knowledge of C and compilation process has gone rusty lately. I was trying to figure out answer to the following question but I could not connect compilation, link and pre-processing phase basics. A quick search on the Google did not help much either. So, I decided to come to the ultimate source of knowledge :)

I know: Variables should not be defined in the .h files. Its ok to declare them there.

Why: Because a header file might get included from multiple places, thus redefining the variable more than one time (Linker gives the error).

Possible work-around: Use header-guards in header files and define variable in that.

Is it really a solution: No. Because header-guards are for preprocessing phase. That is to tell compiler that this part has been already included and do not include it once again. But our multiple definition error comes in the linker part - much after the compilation.

This whole thing has got me confused about how preprocessing & linking work. I thought that preprocessing will just not include the code, if the header guard symbol has been defined. In that case, shouldn't multiple definition of a variable problem also get solved?

What happens that these preprocessing directives save the compilation process from redefining symbols under header guards, but the linker still gets multiple definitions of the symbol?

like image 492
Methos Avatar asked Feb 07 '10 12:02

Methos


People also ask

How do you define a variable in a header?

The clean, reliable way to declare and define global variables is to use a header file to contain an extern declaration of the variable. The header is included by the one source file that defines the variable and by all the source files that reference the variable.

Where should you define variables?

Ideally, declare and define each variable close to where it's first used. A declaration establishes a variable's type. A definition assigns the variable a specific value. In languages that support it, such as C++ and Java, variables should be declared and defined close to where they are first used.

What should I declare in header file?

You should declare it as extern in a header file, and define it in exactly 1 . c file. re-definition is an error but re-declaration is Ok and often necessary. Indeed 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.

Is it acceptable to declare or define a variable in C header?

Variables should not be defined in header files, because the header file can be included in multiple source files, which would cause multiple definitions of the variable. The ANSI C standard will allow multiple external definitions, provided that there is only one initialization.


2 Answers

One thing that I've used in the past (when global variables were in vogue):

var.h file:

... #ifdef DEFINE_GLOBALS #define EXTERN #else #define EXTERN extern #endif EXTERN int global1; EXTERN int global2; ... 

Then in one .c file (usually the one containing main()):

#define DEFINE_GLOBALS #include "var.h" 

The rest of the source files just include "var.h" normally.

Notice that DEFINE_GLOBALS is not a header guard, but rather allows declaring/defining the variables depending on whether it is defined. This technique allows one copy of the declarations/definitions.

like image 82
Richard Pennington Avatar answered Oct 04 '22 06:10

Richard Pennington


Header guard protects you from multiple inclusions in a single source file, not from multiple source files. I guess your problem stems from not understanding this concept.

It is not that pre-processor guards are saving during the compile time from this problem. Actually during compile time, one only source file gets compiled into an obj, symbol definitions are not resolved. But, in case of linking when the linker tries to resolve the symbol definitons, it gets confused seeing more than one definition casuing it to flag the error.

like image 29
Jay Avatar answered Oct 04 '22 07:10

Jay