Search code examples
cstaticconstants

What a C static variable in file scope means?


I have three files to demonstrate the use of static variable in file scope. Variable is declared as extern in file2.h, initialized in file2.c. I am declaring another variable with same name in main.c as static to test for static global scope. But I get the error message "main.c|6|error: static declaration of 'var1' follows non-static declaration.

Could someone explain me the usage of static for file scope?

If I do not include file2.h in main.c, I do not get any problem. But what if I need to use some functions of other files in main.c but still want to keep the variable scope to this file only?

main.c

#include <stdio.h>
#include "file2.h"


static int var1;

    int main()
    {
        printf("value of staticVar1 = %d\n",var1);
        func1();
        printf("value of staticVar1 after function call= %d\n",var1);
        return 0;
    }

file2.h

#ifndef _FILE2_H
#define _FILE2_H
#include <stdio.h>

extern int var1;

int func1(void);

#endif // _FILE2_H

file2.c

#include <stdio.h>
#include "file2.h"

int var1=3;

int func1(void)
{
    printf("value of staticVar1 inside the function = %d\n",var1);
    return(0);
}

Solution

  • #include literally includes the text of its argument. If you include "file2.h", the top of your main.c will have both

    • extern int var1; and

    • static int var1;.

    The compiler won't be able to tell whether you want var1 to be

    • extern (=make it an as-of-yet nonresolved reference to a global scope variable defined with inter-file visibility later or in some other/external compilation unit)

    or

    • static (=place the symbol here but hide it from other compilation units).

    Edit: A more nuanced view of static/extern described here: Using a variable in a file with extern keyword which is defined as static as well as global in the base file?. The caveat is that extern may not make a variable have "external linkage"—it can copy previous linkage (static int x; extern int x /*x is static because of the previous declaration; and you may run into undefined behavior if you use extern at block scope and there are intervening overshadowing variables.)