views:

265

answers:

2

How am I able to access a static variable from another file? Doesn't static variable have a file scope?

bash-3.2$ ls
a.c  b.c

bash-3.2$ cat a.c
#include <stdio.h>
static int s = 100;
int fn()
{
/*  some code */
}

bash-3.2$ cat b.c
#include <stdio.h>
#include "a.c"
extern int s;
int main()
{
printf("s = %d \n",s);
return 0;
}

bash-3.2$ gcc b.c   

bash-3.2$ a.exe
s = 100 
+6  A: 

It's from a separate file, but what you're printing is not from a separate translation unit as you #include the whole of a.c from b.c.

static objects are local to a translation unit, which consists of all included files, and not to a single source file.

Charles Bailey
Doesn't static variable have a file scope?
aks
@aks: No, not if you mean source file.
Charles Bailey
#include is not the same as the "import" or similar that some other languages support. It's more like assembling a single source file by cut-and-pasting in addition "header" files. It's not the same as linking multiple compilation units together - for that, you use a linker to combine the object files generated by the compiler from your source files. The single-source-file case generally gets made easy - two+ files isn't hard, but you do need to know the compiler options etc, or find an IDE that does that for you.
Steve314
@aks: Forget "file scope" and think in terms of translation units (TUs), this use of static means "internal linkage", which you might think of as "TU scope".
Roger Pate
Roger Pate
+5  A: 

You have included one file into another - very bad practice. From C compiler point of view, both files form one translation unit, because C preprocessor inserts the content of a.c into b.c.

In case of two separate translation units, one unit cannot access statics of another, but it's not your case.

If you remove #include "a.c" line and compile like it should be: gcc a.c b.c, you will get unresolved external error for s.

qrdl
Is it not violating or bypassing the definition of a static variable that it has file scope only and can not be accessed from another file?
aks
Static scope is limited to translation unit. In your case both files are one translation unit.
qrdl
As a general rule, I absolutely agree - avoid including source files (as opposed to headers). However, for unit testing the internals of a source file, including the source file provides the test code with access to the otherwise invisible code (variables and functions) - and can be extremely useful. But that is a very specialized context.
Jonathan Leffler
@Jonathan: Very specialized and not worth mentioning due to the confusion for beginners who don't yet grasp the concept of TUs. Also covered under the general rule "Never include implementation (*.c) files as headers" because you're not treating them as headers.
Roger Pate