Reputation: 13
I have two C-files, each having defined a static int variable sharing the same name. My understanding is that static variables declared at top-level should be limited to usage within the same file. However, when I run my program it is obvious that these files affect the value of one another's static variable.
Have I misunderstood how the static keyword works and is there another way to obtain this file-based separation of scopes?
*Edit: Added source code to demonstrate problem. This code is from 3 separate files, as indicated by the comments.
//file 1
static int buffer;
void setter_1(int *input) {
buffer = *input;
}
void getter_1(int *output) {
*output = buffer;
}
//file 2
static int buffer;
void setter_2(int *input) {
buffer = *input;
}
void getter_2(int *output) {
*output = buffer;
}
//main
#include <stdio.h>
#include "buffer_1.c"
#include "buffer_2.c"
int main() {
int int1 = 1;
int int2 = 2;
setter_1(&int1);
setter_2(&int2);
getter_1(&int1);
getter_2(&int2);
printf("%i, %i\n", int1, int2);
return 0;
}
We expected to get two different numbers ("1, 2"), but got two identical numbers ("2, 2").
Thanks in advance
/Frisch
Upvotes: 1
Views: 1289
Reputation: 320719
Even though we often talk about the structure of C program in terms of "files", most of the time what is really meant by "file" is translation unit - a source file together with everything that is #include
d into it.
Now, static
variable in C means a variable with internal linkage, i.e. a variable that is not linkable by name between different translation units. Each translation unit is such case gets its own, completely independent variable. Having multiple translation units in this case is absolutely critical: the separation in question is only possible, again, between different translation units.
In your example you have only one translation unit: you included your .c
files into a single main.c
file, i.e you merged all of your translation units into one translation unit. The title of your question refers to static variable "accessed from another file". In reality there's no "another file" in your example. You have only one "file".
Since you merged everything into a single translation unit, your static variable declarations became repetitive declarations of the same variable inside one translation unit.
Note that your static variable declarations happen to be definitions at the same time. In C++ such repetitive definitions of the same variable would trigger a "multiple definition" error. In C such definitions are treated as tentative definitions (a C-specific feature), which allows them to slip through. But if you add explicit initializers to your static variables (e.g. static int buffer = 0;
) the definitions will no longer be tentative and the code will fail to compile even in C.
If you want to maintain different, independent variables in this case, stop including your .c
files into your main.c
file. Translate each .c
file independently, as a separate translation unit, and then link them together into the final program.
Upvotes: 5
Reputation: 2266
The way you did it, by including file 1 and file 2 in main, you effectively have only one "buffer" variable.
Upvotes: 1
Reputation: 101
I suppose by inclusions you have effectively declared the same static global variable twice, which is why you no longer have two separate variables, but one.
Upvotes: 1
Reputation: 72747
One way this can happen is when pointers to those static variables are passed between functions in the two files:
file1.c:
static int i1;
...
foo(&i1);
file2.c:
void foo(int *ip)
{
*ip = 42;
}
Calling foo in file1.c would modify i1 from a function outside file1.c
Upvotes: 3