1

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

Frisch
  • 13
  • 4
  • 2
    could you provide a small sample of your code? Are these variables declared within a class? – Chris Maes Feb 03 '14 at 16:08
  • The variable is restricted to the file, the memory however is not. If you have a fonction that return the address of this static variable, then another fonction in another file can have access to it. Essentially, you can have a pointer to this static variable. Moreover, as previously mentionned, you should give a small exemple. – NoWiS Feb 03 '14 at 16:10
  • possible duplicate of [Static variable](http://stackoverflow.com/questions/1973162/static-variable) – NoWiS Feb 03 '14 at 16:13
  • 1
    Welcome to Stack Overflow. Please read the [About] page soon. If the two variables are defined `static int i = 0;` in two separate source files, there are two separate variables. You will need to produce an MCRTE ([How to create a Minimal, Complete, Tested and Readable Example](http://stackoverflow.com/help/mcve)), aka MCVE or SSCCE ([Short, Self-Contained, Correct Example](http://sscce.org/)). Clearly, you'll need at least two source files to demonstrate this problem (but they'll be small). You should also identify the platform (o/s, version) and compiler (with version) that you are using. – Jonathan Leffler Feb 03 '14 at 16:19
  • 1
    Static variables declared at top-level **should not** be limited to usage within the same file but their visibility **is** limited to the same file where they are declared in. That's why you can have different static variables with the same name in different files. – Jabberwocky Feb 03 '14 at 16:22
  • don't `#include` c files – Brandin Feb 03 '14 at 19:31

4 Answers4

5

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 #included 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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
3

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

Jens
  • 69,818
  • 15
  • 125
  • 179
1

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.

gmorrow
  • 101
  • 4
1

The way you did it, by including file 1 and file 2 in main, you effectively have only one "buffer" variable.

zentrunix
  • 2,098
  • 12
  • 20