9

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);
}
0

4 Answers 4

6

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

Sign up to request clarification or add additional context in comments.

4 Comments

So that means we cannot include a header file which has a variable with same name that we may intend to make as static. To put it other way, if you want any variable to be in file scope, the same variable should not be defined in header file that may be included. So that means this access control feature of C has this limitation. But if we use a variable in local scope, it is very clean and we do not have this issue and we need not really bother if it is defined elsewhere or not.
Based on various comments, can I say that "File scope static variable" does not make any sense in C?. If we remove static keyword, anyway it becomes global variable through the remainder of the file. Then what is the value addition in using word static? In case we do not include other header files, anyway there will not be any conflict. But if header file is included, we cannot use static for a variable that is in header file. I do not really see any difference between file scope global variable and file scope static variable. Or is my understanding is wrong?
Suppose that in the global scope, you have static int x;. The point of static is that you can have static int x in each translation unit, and those x's won't conflict with each other. As for nonstatic globals, you can only do int x; in one file and all other files that want to use it have to do extern int x;. You can link a file that has int x; with a file that has static int x; but you can't use both at the same time because. You need to choose a different name for your static variable if you want to use the global int x;.
As I said, you're basically doing extern int var1; static int var1 and the compiler is like "Hey, you just told me var1 is an extern global and now you're telling me it's a static global. What's up with that?". The solution is: choose a different name for the static variable or don't refer to the extern one(=don't include the header that refers to it).
6

An object declared at file scope has either external or internal linkage, it cannot have both linkages:

extern int var1;  // declare var1 an int with external linkage
int var1 = 3;     // declare and define var1 with external linkage
static int var1;  // declare and define var1 an int with internal linkage
                  // -> ERROR var1 is redeclared with different linkage

You use static specifier if you want an object with visibility limited to the source file in which you declared it.

Comments

2

If you declare var1 static inside of your main.c it means that this variable shall only be available in this files's compilation unit. It also allows to declare a

static int var1

in each of your .c files without having a conflict because the variable is not exported or made visible to other compilation units / .c files.

extern int var1 

is somewhat the opposite of the static declaration. It says that the var1 variable is not declared here but somewhere else. You would use extern for instance if you have one example.c file where you declare

int var1

and serveral other .c files where you also want to set and read values of that exact variable from example.c. In those .c files you would then declare the variable

extern int var1

telling the compiler that the variable var1 exists but is not declared here. if you forget to really declare the variable inside of example.c but use it with extern in other .c files, you should get a undefined reference error, i think, because variable existance in that case is checked at link time

Comments

1

Putting the external declaration on the header and having the definition on exactly one source file will do. Remove

static int var1;

and you should be fine. You're qualifying a variable with two orthogonal properties: static and extern. The former is to say it'll be visible only within and the latter is to say it'll be referred to externally. This is the reason you see the error.

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

It means whatever is static will have internal linkage. No other TUs will be able to see this symbol outside of the one you've defined it on.

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?

Remove the extern declaration from the header and keep the variable only in main.c.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.