Defining Global Vars In A Header, And Using Them In Multiple C Source


Alex.

Retired
Joined
Aug 24, 2005
Messages
4,616
Here's an abstraction of what I have:

>
header.h
int var = 1;

source1.c
#include "header.h"
if(var == 1) var = 2;

source2.c
#include "header.h"
var++;
>

Good old CodeBlocks screams the following: multiple definition of `var' ... first defined here

I tried doing this to the header, to no avail:

>
header.h
#ifndef _HEADER_
#define _HEADER_ 1
int var = 1;
#endif
>

What's a bloke to do? :(

- Alex
 
header.h
extern int var;

source1.c
#include "header.h"
if(var == 1) var = 2;

source2.c
#include "header.h"
var++;

source3.c
int var = 1;

Hope this helps,
Andrew
 
As Andrew's answer illustrates, it is usually best to not declare variables in .h files.

The purpose of .h files is for type and constant definitions, prototypes, and 'extern' declarations to help the linker find stuff declared in your source files.
 
If you don't want to type your variables everytime, you can always do something like:

--- header.h ---

#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#ifdef DEFINE_VARS
#define EXTERN
#else
#define EXTERN extern
#endif

EXTERN int var;
#endif

--- source1.c ---
#include "header.h"

var ++

--- source2.c ---
#include "header.h"

var = 0;

--- source3.c ---
#define DEFINE_VARS
#include "header.h"

Note however you can't initialise them if you define them like this, but since global variables go into the BSS region, you can assume they'll be set to zero by the compilers startup code.
 
Thank you all, you helped me heaps :)

I ended up using

header.h
int var;

source1.c
#include "header.h"
var = 1;

source2.c
#include "header.h"
if(var == 1) var = 2;

which works great.

Not knowing C by the book I always seem to stumble across technicalities like these, good thing this community is so helpful. I should look more into the extern type, it looks useful.

- Alex
 
Alex, that's still not a canonical way of doing it. Normally you'd only declare the variable in the header, using extern, and define it in exactly one compiled source file. 'extern' isn't a type, it's a modifier for the declaration which makes it declare that the variable exists, but not define it at this point. It's exactly what you want for declaring global variables in header files.

If the code you just posted did compile and link, it's probably due to the linker not being strict - for legacy reasons ("extern" didn't exist originally), linkers can usually coalesce duplicate variables, provided they don't have differing initialization values. It's bad practice though - much better to use "extern" since that's what it's there for.

Note the strict distinction between "define" and "declare". You should wrap your entire header file in multiple inclusion guards (as you did), in case it indirectly gets included more than once in a compilation unit (.c or .cpp file), as that protects against multiple declaration. You should also use extern, and define globals in one .cpp file only, to protect at link-time against multiple definitions of the same symbol. The two kinds of error are similar at first sight, but quite different in what's actually being complained about.

BTW, it's also good to include the header declaring the variable in the source file that defines the variable - this way the compiler gets to check that the declaration really does match the definition. Similarly, it can check that function prototypes match, etc. There are actually compiler options you can use to ensure you never create a global without having first included a header declaring it - I've found them useful in the past, if a bit pedantic.

(Edit: by the way, the comp.lang.c FAQ is a really good place to look for basic programming problems like this - while it's a long document, individual answers are short and to-the-point, and almost always 100% pedantically correct.)
 
All right, I'm always up for improving my coding practices. :) It compiles ok, although I get the following warning:

Code:
data definition has no type or storage class

- Alex
 
Alex. posted on Aug 19 2006 at 01:59 PM said:
All right, I'm always up for improving my coding practices. :) It compiles ok, although I get the following warning:

Code:
data definition has no type or storage class

- Alex
source1.c
#include "header.h"
var = 1;

should be

source1.c
#include "header.h"
int var = 1;
 
Last edited by a moderator:
Well that certainly did it! Thank you yaustar!

Again, thank you all very much for your help, the devvers in this community certainly are kind and helpful people. :)

- Alex
 
Back
Top