简体   繁体   中英

extern variable

how to use a variable defined in a header, and using them in multiple source files using extern. I am getting multiple definition error.

A good rule to follow is: "Don't define things in header files". Declare all you want but definitions should be restricted to non headers. A declaration is simply a notification that something exists. A definition actually defines what it is.

The rationale behind this guideline is to prevent exactly the situation you're seeing - having things define twice (or more) because header files are included into multiple compilation units.

To avoid this, you could use something like:

myprog.h:
    extern int myVar;     // a declaration.

myprog.c:
    #include "myprog.h"
    int myVar = 7;        // a definition.

otherbit.c:
    #include "myprog.h"
    int fn (void) {
        myVar = 12;
        return myVar;
    }

The definition above will only end up in myprog.o , you won't get another copy in otherbit.o to cause you problems at link time.

Leaving aside that proper encapsulation would make these global variables a very bad idea, that's the way I'd do it.

The encapsulated way of doing it would be something like this:

myprog.h:
    int getMyVar (void);
    void setMyVar (int);

myprog.c:
    #include "myprog.h"
    static int myVar = 7;
    int getMyVar (void) { return myVar; }
    void setMyVar (int n) {
        // Error checks on n here.
        myVar = n;
    }

otherbit.c:
    #include "myprog.h"
    int fn (void) {
        setMyVar (12);
        return getMyVar();
    }

Encapsulation is basically information hiding. It means you should expose as little as possible of your inner working to get the job done, lest you open yourself up the possibility of other code sneaking in under the covers and either invalidating your assumptions (see below) or making it harder to change your inner workings later.

A classic example is if you want the myVar variable restricted to the range 0 through 359 inclusive (say an angle). With encapsulation you could simply use:

void setMyVar (unsigned int n) { myVar = n % 360; }

and never have to worry about it being invalid. You can safely assume, memory corruption aside, that myVar will always be within the range desired. You would not have that certainty if some rogue piece of user code could come in and just do:

myVar = 32767;

without you knowing it. You would either have to cater for values outside your desired range or force it to the valid range at the start of all your functions:

myVar = myVar % 360;

That's poor coding practice, and totally unnecessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM