0

After I read about static variables, something confuses me. We can say the keyword static acts to extend the lifetime of a variable to the lifetime of the program because the lifetime of a variable is the period over which it exists.

My questions are:

  1. What really happens inside?
  2. Is memory allocated specifically for this variable, or is it a kind of pointer?
pipors
  • 11
  • 1
  • 2
    If you want to get pedantic it's likely up to the compiler, but in practice it just means it reserves memory for that value to persist between calls, as in it is not on the stack. – tadman Dec 22 '22 at 01:18
  • 1
    Remember "pointer" effectively means "memory address" and in C almost anything has or can have one of those. – tadman Dec 22 '22 at 01:19
  • 4
    You are talking about static variables declared inside a function, right? A good "Mental Model" is to think of those as normal global variables where the name is only visible inside the given function. – HAL9000 Dec 22 '22 at 01:52
  • 1
    One subtle point: You should have a good reason before using static variables inside functions... Use this sparingly as your readers will notice that some variables are 'static' and spend/waste time wondering why... – Fe2O3 Dec 22 '22 at 03:10
  • static storage should be generally avoided as it likely makes functions non-reentrant. – Marco Dec 22 '22 at 03:15

4 Answers4

5

Depending on how you count, in a traditional memory architecture there are typically up to five different places to store the data used by a C program:

  1. On the stack.
  2. In the initialized data segment.
  3. In the uninitialized data segment ("bss").
  4. In the code segment.
  5. In the heap.

Variables declared local to functions (those with "automatic" storage duration) are stored in #1, on the stack.

Global variables (those declared outside of a function) are stored in 2, 3, or maybe 4, depending on whether they're initialized, uninitialized (meaning that they default to 0), or const. These variables have "static" duration.

And since static-local variables have static duration, also, they're also stored in 2, 3, or maybe 4.

I mentioned #5 "the heap" for completeness, but no conventionally-declared variables are ever going to be stored there.

See also Difference between static global variable and non-static global variable in C.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Can you give any reference of data being stored in code segment? – H.S. Dec 22 '22 at 09:04
  • @H.S. No, I can't. I'm reasonably sure I've heard that it's possible, and occasionally practiced, to put const-qualified data into the readonly text segment (which is obviously advantageous for shared libraries), but in a simple test just now I couldn't demonstrate it. (But that's why I said "or maybe 4".) – Steve Summit Dec 22 '22 at 14:37
  • @H.S. I belatedly remember: given `char *p = "Hello, world!";`, these days the pointed-to string is typically stored in the text segment. – Steve Summit Jan 03 '23 at 19:29
2

We can say the keyword static acts to extend the lifetime of a variable to the lifetime of the program because the lifetime of a variable is the period over which it exists.

This is true for static variables defined inside a function like:

int *my_function() {
     static int my_static_var[4] = {0,0,0,0};

     return my_static_var;
}

Here my_static_var's lifetime is the lifetime of the program never goes out of scope³, so it's valid to access the memory after the function has returned.

However, all calls to this (my_function) function will return the exact same block of memory, so conceptually it's really a global variable that can't be accessed directly outside of the function.

Of course, you can also define variables outside a function:

static int my_static_var[4]; 

Here my_static_var is only accessible within the same translation unit.

That means another "file" cannot directly² access my_static_var; it's bound to the file it was defined in.

Also, all globally defined variables are automatically initialized to 0

Note you cannot declare a static variable, since static variables are intentionally not shared with other parts of your source code. You always have to define (declaration / definition are two different things) it.

The same concept can be applied to static functions:

static int my_function() {
    return 0;
}

Here the function my_function cannot be accessed directly outside the translation unit it was defined in.

I don't know of any other uses for the static keyword in C.

¹ The same applies to static variables defined inside a function.

² It would still be possible through a pointer, for example.

³ Variable goes out of scope, see comment from @Eric Postpischil

Marco
  • 7,007
  • 2
  • 19
  • 49
  • 2
    Inside a function or out, `static` objects initialize via the same rules at program start. – chux - Reinstate Monica Dec 22 '22 at 02:44
  • @chux-ReinstateMonica That's good to know, so `static` variables inside a function get initialized to `0` as well then? I'm not using `static` variables inside a function (in my code) at all, so I'm not familiar with it. – Marco Dec 22 '22 at 02:48
  • The initialization rules are more nuanced than "get initialized to `0`", bit close enough. Its more like objects get a zero bit pattern.. With FP and pointers, that is not specified a value of `0`, yet overwhelming is. – chux - Reinstate Monica Dec 22 '22 at 02:54
  • 1
    "my_function cannot be accessed outside the translation unit " is more like "my_function cannot be accessed _directly_ outside the translation unit " A pointer to that `static` function could be passed around and used anywhere. – chux - Reinstate Monica Dec 22 '22 at 03:01
  • Re “Here `my_static_var` never goes out of scope, so it's valid to access the memory after the function has returned.”: Scope is about **where** in source code an identifier is visible. Lifetime is about **when** an object exists (has memory reserved for it). The scope of `my_static_var` does not control when its object can be accessed. – Eric Postpischil Dec 22 '22 at 03:33
  • @EricPostpischil I'm having a bit of a hard time getting on what you're about. I understand that a scope doesn't necessarily define the lifetime of an object (nested blocks inside a function create separate scopes, but the variables still live on the same stack frame). But at the same time, I think `variable goes out of scope` is a pretty known way of saying that a variable is no longer valid eh? Maybe I'm wrong but I don't really see an issue with `goes out of scope`. You can probably tell that I'm a bit confused, so please clear me up if you can :) – Marco Dec 22 '22 at 03:47
  • 1
    Consider `void foo(void) { int x = 3; bar(&x); } void bar(int *p) { *p = 4; }`. `x` is not in scope in `bar`. The moment `bar` is called, program execution transfers to code for which `x` is not in scope. Yet it is within the lifetime of `x`, and `x` may safely be accessed, via the pointer `p`. Therefore, whether a variable’s identifier is in scope or not does not tell you whether it may safely be accessed or whether it is within its lifetime. Using “scope” to refer to lifetime is wrong. Simply say “`x`’s lifetime ends,” not “`x` goes out of scope.” – Eric Postpischil Dec 22 '22 at 12:36
  • @EricPostpischil Oh, thank you! That's kind of a revelation for me. I will update my post. – Marco Dec 22 '22 at 21:54
  • @EricPostpischil I'm always a bit hesitant to answer such questions because I know for a fact, that there are people (chux, you and some others) that definitely know a lot better than I do. But I have to say, giving it a shot and getting corrected always lead me to learn something new. C really is a much bigger beast than I ever anticipated. So thank you for correcting me! I appreciate it very much :) – Marco Dec 22 '22 at 21:58
0

There are two different, mostly unrelated, concepts called static in C

  • "static storage duration" (sometimes called "static lifetime") which applies to objects
  • "static scope", which applies to names. Most places in the spec actually call this "internal linkage" to try to reduce the confusion around "static"

More confusingly, the static keyword can affect either concept, depending on where it is

  • outside of any function body, static causes a name declared to have static scope (or internal linkage) instead of global scope (or external linkage), but does not affect the object's lifetime (which will be static for all objects defined outside of functions, regardless of the presence or absence of the keyword)
  • inside of a function body, static causes objects defined to have static storage duration (lifetime), but does not affect the name's scope (which will always be local)
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • 1
    C does not have global scope or static scope. It has external linkage, internal linkage, and no linkage. It has file scope, function scope, function parameter scope, and block scope. External linkage is not the same as global scope. – Eric Postpischil Dec 22 '22 at 03:29
  • 1
    @EricPostpischil external linkage and internal linkage are somwhat obscure variant names for global scope and static scope. Everyone except the C committee uses the word "scope" to mean this – Chris Dodd Dec 22 '22 at 05:30
  • Baloney. They are not obscure; they are routinely used. An external linkage is not global scope. To be global scope, a declaration anywhere in the program would have to be visible everywhere in the program (except where hidden). C does not have that. To have an identifier visible in multiple translation units, it must be declared in multiple translation units, and those separate declarations must be linked together. That is a technical difference, and it matters in practice as it can cause link issues that would not exist with global scope. – Eric Postpischil Dec 24 '22 at 00:18
-1

In a C program, the static keyword is used to declare

  1. Scope a function or a variable within the file it is defined. This function or variable is private to the file.

  2. Keep the state of a variable among functions in the same file.

yoonghm
  • 4,198
  • 1
  • 32
  • 48