Static Global Variables in C++

When to use static keyword before global variables?

static renders variable local to the file which is generally a good thing, see for example this Wikipedia entry.

Difference between static global variable and non-static global variable in C

There are basically four cases:

  • declared outside of function, without static
  • declared outside of function, with static
  • declared inside of function, without static
  • declared inside of function, with static

Let's cover these in turn.

Declared outside of function, without static

This is a conventional global symbol. You can access it from any source file (although in that other source file, you typically need an extern declaration).

Declared outside of function, with static

This is the "static" global you were asking about. You can access it only within the source file where it is defined. It's "private" to that source file, but you can access it from any function in that source file (well, actually, any function in that source file that occurs below its declaration). Like any global variable, it maintains its value for the life of the program.

Declared inside of function, without static

This is a conventional local variable. You can access it only within that function. Each time the function is called (including recursively), you get a new instance of the variable. If you don't initialize it, it starts out containing an unpredictable value. It does not maintain its value between calls.

Declared inside of function, with static

This is a static local variable. You can access it only within that function. There is exactly one copy of it, shared between all calls to the function (including recursive calls). If you don't initialize it, it starts out zero. It maintains its value between calls.

In three of these cases, if you don't provide an explicit initializer, a variable is guaranteed to be initialized to 0. But in the case of true local variables, if you don't provide an explicit initializer,
it starts out containing an unpredictable value, which you can't depend on.

Formally, there are two concepts here, visibility and lifetime. True global variables are visible anywhere in the program. Static global variables are visible only in their source file. Local variables are visible only in their function. All global variables, and all static variables, have static duration — they last for as long as the program does. (Also these are the ones that are guaranteed to be initialized to 0.) True local variables have "automatic" duration — they come and go as the containing function is called and returns.

Closely related to duration is the question of where variables will actually be stored. Static-duration variables are typically stored in the data segment. Automatic-duration variables are typically — though not necessarily — stored on the stack.

What is the Static Global Variable Purpose?

The term "maintaining last value" causing the confusion for you. The term "maintaining last value" would be used on the context of function local variable vs function static variable. Because variable declared within a function got stored in stack, and on exiting the function will be cleared the stack used by that function which leaves the variable dead.

But creating a function local variable with static is creating a memory in RAM(and not in stack), which allows the memory to hold even after exit of the function. Even the global variables and file static variables are stored in RAM thereby retaining its value forever.

So, for your question any variable stored in RAM will "maintain its last value" irrespective of its keyword static. But the static limits its scope of its usage, ie., if declared in the file scope then it can be used(accessed) within the file, if declared in the function scope then its scope limits within the function alone.

Reference static global variable from a different file

I've read that the static keyword makes a global variable "private", accessible only from the file it's been defined.

That is approximately correct, but very misleading if you don't recognize that the word "file" is being used as a simpler stand in for the more correct term "translation unit". The latter can be viewed as the composite code formed from a source file by (pre)processing all the #include and conditional-inclusion directives within. That forms one logical unit of source code for compilation ("translation" in the standard's terminology).

Thus, when one talks about static declarations being scoped to one file, one means a file intended to be the main file of a translation unit. We thereby identify the TU with that file. This is in fact the essential difference between header files (.h) and source files (.c) -- both contain C source code, but the latter are meant to be compilation starting points, whereas the former are not. That's also why one should never #include a .c file.

I thought static variables couldn't be accessed from other files. Why
was I able to access a static variable from a different file?

Because you're interpreting "file" differently than it was meant in the claim you're referring to, and because you have violated the strong convention supporting that word usage by #includeing one .c file into another. You are compiling just one translation unit, and all file-scope declarations of all contributing files (filesystem sense) are visible within.

Whether Global Variables in C, static or extern?

Global Variable in C by default corresponds to static storage class but has external linkage. Does this mean it is partially static and partially extern?

The English word “static” has muddled and multiple meanings in C, and, yes, the default for a variable declared outside a function is to have static storage duration and external linkage.

Because there are multiple concepts here and some mixed use of word meanings, we should clarify some terminology and formatting:

  • Use code style to refer to specific text in source code, such as the keyword static. When speaking of static storage duration or external linkage, “static” and “external” are mere English adjectives and should not be in code style.
  • “Global” means visible throughout an entire program. The C standard does not use this word for this purpose. It uses “external” to refer to things that are outside of (external to) any function. (But it also uses “external” for other purposes.) A global variable could not have internal linkage, because it would not be visible throughout the entire program.
  • A variable consists of an object (memory reserved for representing the value) and an identifier (the name). Storage duration is a property of the object. Linkage is a property of the identifier.

The English word “static” generally means unchanging. The C standard uses this word and the keyword static in multiple ways:

  • Static storage duration means the memory for an object is reserved throughout all of program execution.
  • Using the static keyword in a declaration, other than as below, both gives an object static storage duration and, in a declaration outside a function, gives the identifier internal linkage.
  • Using the static keyword inside subscript markers in a parameter declaration, as in void foo(int a[static 3]), indicates that the parameter points to at least the stated number of elements.
  • Static assertions, using _Static_assert, provide compile-time tests (which can help detect bugs or ensure a program is being compiled with expected settings).

These multiple uses are unfortunate and are due at least partly to the history of how the C language was developed.

C local and global static variables

You messed up all. Static local variable is a place to hide data from other functions but retain data for future calls of that function.

Static global variables have

  • static storage duration (Retain data for future call)
  • internal linkage (variable is restricted to single file) and
  • file scope (Only in the current file the variable can be referenced)

Static local variables have

  • static storage duration
  • no linkage
  • block scope

Global variables in C are static or not?

If you do not specify a storage class (that is, the extern or static keywords), then by default global variables have external linkage. From the C99 standard:

§6.2.2 Linkages of identifiers

3) If the declaration of a file scope identifier for an object or a function contains the storage-class specifier static, the identifier has internal linkage.

5) If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

So even if you don't specify the extern keyword, globals can still be accessed by other source files (so-called translation units), because they can still have an extern declaration for the same variable. If you use the static keyword to specify internal linkage, then even in the presence of an extern declaration for the same variable name in another source file, it will refer to a different variable.



Related Topics



Leave a reply



Submit