0

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 
aks
  • 4,695
  • 8
  • 36
  • 37
  • 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 Feb 22 '10 at 14:01
  • 3
    *Never* #include *.c, *.cpp, etc. files as headers. –  Feb 22 '10 at 14:38

2 Answers2

6

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
  • 34,062
  • 14
  • 56
  • 86
  • 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 Feb 22 '10 at 14:00
  • Static scope is limited to translation unit. In your case both files are one translation unit. – qrdl Feb 22 '10 at 14:01
  • 1
    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 Feb 22 '10 at 14:24
  • 2
    @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. –  Feb 22 '10 at 14:46
5

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.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • Doesn't static variable have a file scope? – aks Feb 22 '10 at 13:59
  • @aks: No, not if you mean source file. – CB Bailey Feb 22 '10 at 14:02
  • 2
    #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. –  Feb 22 '10 at 14:17
  • 1
    @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". –  Feb 22 '10 at 14:40
  • 1
    @Steve314: gcc (and most C compilers I've ever used) make it really easy, no matter how many files: `gcc a.c b.c`. A 15 minute make tutorial that covers implicit rules and CFLAGS covers the rest. (`echo a.exe: a.o b.o >>Makefile && make a.exe`) –  Feb 22 '10 at 14:43