Hi everyone,
I would like to know if something similar happen to you. Well the issue is that when I declare a variable as a global one in the header file of a module with extern sometimes it loses its value. And if I declare it as static I can not access to it from other module. As far As I understand, a static variable is the same during the all of the execution of the program and it has a space of memory reserved to it. Can anyone please clarify this?
Thanks in advance.
You should have the extern declaration in the header:
extern int aDeviceList[MAX_DEVICE_NUMBER];
And the Definition in exactly one 'C' file:
int aDeviceList[MAX_DEVICE_NUMBER];
Then other 'C' files needing to access that variable just #include the header.
c-faq.com/.../decldef.html
"So what I really want to know if it is appropriate to use extern variables to transfer values between modules and functions"
It cam be - when done properly & appropriately.
Having the definition in the header means that each 'C' file which #includes that header has its own definition.
Close, but no cigar. Having the same external, non-initialized definition occur repeatedly does open a nasty can of worms. But it doesn't mean you get multiple definitions.
An external definition without an initializer is a "tentative definition". Multiple tentative definitions of the same object are allowed inside one translation unit ... they're contracted into a single end definition and otherwise treated like declarations. I.e.
int foo[5]; int foo[5]; /*rest of source*/
is allowed, and defined to behave as if you had written
extern int foo[5]; extern int foo[5]; /*rest of source*/ int foo[5] = {0,0,0,0,0};
But the language definition only allows this within one translation unit. If you have a set of tentative definitions spread over multiple source units, you directly violate a "shall" rule of the C standard (C99 6.9 p5). That makes this undefined behaviour.
By far the most common realizations of this undefined behaviour are:
1) Linker flat-out rejects it, with an error message about a "multiply defined" symbol.
2) Merging of tentative definitions is extended across translation units; you get a single defined object in the global namespace.
I'm reasonably sure I've never seen a linker split up the set of tentatives into multiple internally linked objects, as suggested by Andy above. While that would be allowed, too, as the behaviour is, after all, undefined, it'd be a seriously nasty implementation, indeed.
"An external definition without an initializer is a "tentative definition". Multiple tentative definitions of the same object are allowed inside one translation unit"
Indeed.
"I'm reasonably sure I've never seen a linker split up the set of tentatives into multiple internally linked objects, as suggested by Andy above"
The thread title speaks of 'static'...
If you have static definitions in a header, then you will get the "multiple internally linked objects". Perhaps this is what's happening in the OP's case: he has multiple file-scope variables with the same name, and is looking at the "wrong" one - so it appears to have "lost" the value he was expecting...?
Quite unfornuately the word "static" means just enough different things in discussions about C programming (let alone C++ or Java) that its mention alone means either everything or nothing at all. Overloading 'static' to mean two such different things as "static duration" and "internal linkage" may have to be called the worst design decision in the C programming language.
The OP's code fragment shown mid-thread, which we seem to be discussing now, had no 'static'. If there had been a "static" in that header fragment, it would have collided with the "extern" in the C source, and caused a compilation error.
So while it's possible that the OP's real code (which is probably quite different from the fragments shown) contains a strategically well-misplaced "static", I'll consider that highly unlikely until confirmed by OP.