#24916 - isildur - Fri Aug 13, 2004 4:33 pm
Hi,
I'm having a strange problem I never had when using the vc compiler.
For gba dev I use devkitARM.
Let's say I have 2 different C files, I will call them file1.c and file2.c.
I declare a global var with the same name and type in each of the 2 files like this:
int testVar = 0;
Both files have this and those variables are not declared as extern anywhere in other modules. But the linker complains of multiple definition of 'testVar'.
Those global vars should each have their own file scope? No?
What am I doing wrong?
#24918 - poslundc - Fri Aug 13, 2004 4:42 pm
Variables on the global scope are, by default, global (and visible) to all modules.
You can declare a global as belonging to a single C file by prefixing it with the "static" keyword. (Not to be confused with the bajillion other purposes shared by the static keyword.) The same applies to functions you don't want conflicting with functions in other C files.
Dan.
#24919 - isildur - Fri Aug 13, 2004 5:04 pm
Thanks for the fast answer. The compiler/linker in Visual Studio does not require the static keyword for globals. The global vars have file scope and have to be declared as extern in other files to be visible.
But if I declare it like you said:
static int testVar = 0;
in both modules, are they separate variables or the same?
#24921 - poslundc - Fri Aug 13, 2004 5:20 pm
They will be separate variables.
More detailed explanation: anything global in a C file (in other words, global variables and functions not declared static) generates a symbol at compile time that is left in the object (.o) file. When it comes time to link your various modules together into an elf file (.elf), the linker uses those symbols to connect them together.
Functions and global variables declared static have file scope only, and do not generate those symbols, so you cannot reference them from other modules when linking either intentionally or by accident (as in your situation).
Dan.
#24924 - torne - Fri Aug 13, 2004 5:38 pm
The 'extern' bit only tells the *compiler* which variables exist in other modules; it has nothing to do with the linker. The reason it works in VC++'s linker in the way you expect is just because their linker is more 'lenient' with things that are possible problems; the MS linker will usually emit a warning for this case but Visual Studio has a nice habit of decreasing the warning levels of the tools it calls. =)
#24931 - sajiimori - Fri Aug 13, 2004 6:07 pm
Yeah, the older C standard allowed global variable to be declared in multiple files, and the linker would consider them the same variable. That behavior has been deprecated ever since the "extern" keyword was introduced (which is to say, a long time ago).
So just to reiterate what Dan essentially said: "global scope" and "file scope" are mutually exclusive. "Global" doesn't just mean visible to multiple functions -- it means visible to the entire project. Modern compilers will complain if you reference a global symbol that hasn't been declared (mostly because it doesn't know its type), but the symbol is there nonetheless.
#24937 - isildur - Fri Aug 13, 2004 6:48 pm
Thanks to all for the answers. :)