52

I have seen static structure declarations quite often in a driver code I have been asked to modify.

I tried looking for information as to why structs are declared static and the motivation of doing so.

Can anyone of you please help me understand this?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
kutty
  • 541
  • 1
  • 4
  • 4

5 Answers5

45

The static keyword in C has several effects, depending on the context it's applied to.

  • when applied to a variable declared inside a function, the value of that variable will be preserved between function calls.
  • when applied to a variable declared outside a function, or to a function, the visibility of that variable or function is limited to the "translation unit" it's declared in - ie the file itself. For variables this boils down to a kind of "locally visible global variable".

Both usages are pretty common in relatively low-level code like drivers.

The former, and the latter when applied to variables, allow functions to retain a notion of state between calls, which can be very useful, but this can also cause all kinds of nasty problems when the code is being used in any context where it is being used concurrently, either by multiple threads or by multiple callers. If you cannot guarantee that the code will strictly be called in sequence by one "user", you can pass a kind of "context" structure that's being maintained by the caller on each call.

The latter, applied to functions, allows a programmer to make the function invisible from outside of the module, and it MAY be somewhat faster with some compilers for certain architectures because the compiler knows it doesn't have to make the variable/function available outside the module - allowing the function to be inlined for example.

fvu
  • 32,488
  • 6
  • 61
  • 79
  • 3
    With caution? Why that? Use them when you need an object with static storage duration or internal linkage. Everything else is handwaving. – Jens Sep 02 '11 at 20:24
  • 1
    @Jens not a native speaker either, I just wanted to point out (tongue in cheek fashion) that there are definitely real potential dangers to static storage - I hope you find my reformulation clearer? – fvu Sep 02 '11 at 20:49
  • 4
    Yes, thanks. The original wording could have been misinterpreted by beginning C programmers to develop a misconception along "Oh, static variables must be used with caution, so they must be bad in some way. I should avoid them, just like gotos and setjmp." They have their use, and are even encouraged by programming guidelines valuing smallest possible linkage of identifiers. – Jens Sep 02 '11 at 21:04
  • 3
    @Jens true, that's why I welcomed this opportunity to improve the text. – fvu Sep 02 '11 at 21:13
  • 1
    @fvu: I like the improved text. Another point to mention about `static` variables used within a function is that it's sometimes good to define a parameter or combination of parameter values that can be used to "reset" the values. Having all access to some variables be confined to a function can make it easier to reason about them, but if no provision is made to reset them when the function is written, it may be difficult to add one in if it later becomes necessary to run the function multiple times "from scratch" (as may be common in some test scenarios). – supercat Jul 02 '15 at 14:48
41

Something that apparently all other answers seem to miss: static is and specifies also a storage duration for an object, along with automatic (local variables) and allocated (memory returned by malloc and friends).

Objects with static storage duration are initialized before main() starts, either with the initializer specified, or, if none was given, as if 0 had been assigned to it (for structs and arrays this goes for each member and recursively).

The second property static sets for an identifier, is its linkage, which is a concept used at link time and tells the linker which identifiers refer to the same object. The static keyword makes an identifier have internal linkage, which means it cannot refer to identifiers of the same name in another translation unit.

And to be pedantic about all the sloppy answers I've read before: a static variable can not be referenced everyhere in the file it is declared. Its scope is only from its declaration (which can be between function definitions) to the end of the source file--or even smaller, to the end of the enclosing block.

Tommy
  • 99,986
  • 12
  • 185
  • 204
Jens
  • 69,818
  • 15
  • 125
  • 179
31

struct variable

For a struct variable like static struct S s;, this has been widely discussed at: What does "static" mean in C?

struct definition: no effect:

static struct S { int i; int j; };

is the exact same as:

struct S { int i; int j; };

so never use it. GCC 4.8 raises a warning if you do it.

This is because struct definitions have no storage, and do no generate symbols in object files like variables and functions. Just try compiling and decompiling:

struct S { int i; int j; };
int i;

with:

gcc -c main.c
nm main.o

and you will see that there is no S symbol, but there is an i symbol.

The compiler simply uses definitions to calculate the offset of fields at compile time.

This is struct definitions are usually included in headers: they won't generate multiple separate data, even if included multiple times.

The same goes for enum.

C++ struct definition: deprecated in C++11

C++11 N3337 standard draft Annex C 7.1.1:

Change: In C ++, the static or extern specifiers can only be applied to names of objects or functions Using these specifiers with type declarations is illegal in C ++. In C, these specifiers are ignored when used on type declarations.

See also: https://stackoverflow.com/a/31201984/895245

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
9

If you declare a variable as being static, it is visible only in that translation unit (if globally declared) or retains its value from call to call (if declared inside a function).

In your case I guess it is the first case. In that case, probably the programmer didn't want the structure to be visible from other files.

Mihai Maruseac
  • 20,967
  • 7
  • 57
  • 109
  • 1
    This is very imprecise. 1) The scope ("visibility"?) of a static declared identifier is not the translation unit, but from after the declaration to the end of the enclosing block, or the end of the file if declared at file scope. 2) The linkage is internal. 3) Even at file scope, statics retain their value. – Jens Sep 03 '11 at 08:46
  • Yeah, I know. But I thought that that info was unimportant to this questions's point of view. – Mihai Maruseac Sep 03 '11 at 08:53
  • 1
    I think that when teaching we help the students most with proper terminology and precision. A C identifier has associated with it scope, linkage, storage duration, name space and type. I try not to assume what the student may deem important because I'm known to get things wrong :-) – Jens Sep 03 '11 at 09:46
7

The static modifier for the struct limits the scope of visibility of the structure to the current translation unit (i.e. the file).

NOTE: This answer assumes (as other responders have indicated) that your declaration is not within a function.

Brandon E Taylor
  • 24,881
  • 6
  • 47
  • 71
  • 1
    Pedantic note: "(i.e. the file)" is wrong. The scope starts after the declaration. Function definitions before that can not refer to variables declared later (whether static or extern). – Jens Sep 02 '11 at 20:17