Usually, you will see the static keyword in these places:

  1. A static variable inside a function keeps its value between invocations.
  2. A static global variable or function is "seen" only in the file in which it's declared.

(1) is the more foreign topic if you're a newbie, so here's an example:

#include <stdio.h>

void foo()
{
    int a = 10;
    static int sa = 10;
    
    a += 5;
    sa += 5;
    
    printf("a = %d, sa = %d\n", a, sa);
}


int main()
{
    int i;
    
    for (i = 0; i < 10; ++i)
        foo();
}

This prints:

a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60

This is useful for cases where a function needs to keep some state between invocations, and you don't want to use global variables. Beware, however, this feature should be used very sparingly - it makes your code not thread-safe and harder to understand.

(2) is used widely as an "access control" feature. If you have a .c file implementing some functionality, it usually exposes only a few "public" functions to users. The rest of its functions should be made static, so that the user won't be able to access them. This is encapsulation, a good practice.

Quoting Wikipedia:

In the C programming language, static is used with global variables and functions to set their scope to the containing file. In local variables, static is used to store the variable in the statically allocated memory instead of the automatically allocated memory. While the language does not dictate the implementation of either type of memory, statically allocated memory is typically reserved in data segment of the program at compile time, while the automatically allocated memory is normally implemented as a transient call stack.

See here and here for more details.

And to answer your second question, it's not like in C#.

In C++, however, static is also used to define class attributes (shared between all objects of the same class) and methods. In C there are no classes, so this feature is irrelevant.


Additionally, in C, static can be used in array declarators to specify minimum size of the array (non-function array declarators cannot use this keyword). Consider this declaration:

void func(int foo[static 42]);

The function func() takes an array of at least 42 elements.

Note that C++ does not support this use of the static keyword.

Answer from Eli Bendersky on Stack Overflow
Top answer
1 of 16
1931

Usually, you will see the static keyword in these places:

  1. A static variable inside a function keeps its value between invocations.
  2. A static global variable or function is "seen" only in the file in which it's declared.

(1) is the more foreign topic if you're a newbie, so here's an example:

#include <stdio.h>

void foo()
{
    int a = 10;
    static int sa = 10;
    
    a += 5;
    sa += 5;
    
    printf("a = %d, sa = %d\n", a, sa);
}


int main()
{
    int i;
    
    for (i = 0; i < 10; ++i)
        foo();
}

This prints:

a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60

This is useful for cases where a function needs to keep some state between invocations, and you don't want to use global variables. Beware, however, this feature should be used very sparingly - it makes your code not thread-safe and harder to understand.

(2) is used widely as an "access control" feature. If you have a .c file implementing some functionality, it usually exposes only a few "public" functions to users. The rest of its functions should be made static, so that the user won't be able to access them. This is encapsulation, a good practice.

Quoting Wikipedia:

In the C programming language, static is used with global variables and functions to set their scope to the containing file. In local variables, static is used to store the variable in the statically allocated memory instead of the automatically allocated memory. While the language does not dictate the implementation of either type of memory, statically allocated memory is typically reserved in data segment of the program at compile time, while the automatically allocated memory is normally implemented as a transient call stack.

See here and here for more details.

And to answer your second question, it's not like in C#.

In C++, however, static is also used to define class attributes (shared between all objects of the same class) and methods. In C there are no classes, so this feature is irrelevant.


Additionally, in C, static can be used in array declarators to specify minimum size of the array (non-function array declarators cannot use this keyword). Consider this declaration:

void func(int foo[static 42]);

The function func() takes an array of at least 42 elements.

Note that C++ does not support this use of the static keyword.

2 of 16
295

There is one more use not covered here, and that is as part of an array type declaration as an argument to a function:

int someFunction(char arg[static 10])
{
    ...
}

In this context, this specifies that arguments passed to this function must be an array of type char with at least 10 elements in it. For more info see my question here.

🌐
GeeksforGeeks
geeksforgeeks.org › c language › static-variables-in-c
Static Variables in C - GeeksforGeeks
In C programming, a static variable is declared using static keyword and have the property of retaining their value between multiple function calls. It is initialized only once and is not destroyed when the function returns a value.
Published   July 23, 2025
Discussions

microcontroller - Concept of the static keyword from the perspective of embedded C - Electrical Engineering Stack Exchange
This line is declared as a global variable inside a header file (.h). So, from what I came to know about the C language, a "static global variable" is not visible to any other file - or, simply, static global variables / functions cannot be used outside of the current file. Then, how can this keyword ... More on electronics.stackexchange.com
🌐 electronics.stackexchange.com
July 8, 2019
The static keyword and its various uses in C++ - Stack Overflow
The keyword static is one which has several meanings in C++ that I find very confusing and I can never bend my mind around how its actually supposed to work. From what I understand there is static More on stackoverflow.com
🌐 stackoverflow.com
programming languages - False friends? Keyword "static" in C compared to C++, C# and Java - Software Engineering Stack Exchange
To me, the use of the keyword static in C and languages like C# and Java are "false friends" like "to become" in English and "bekommen" in German (= "to get" in English), because they mean different More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
March 28, 2012
What does Static keyword do in C++?
The static keyword has multiple unrelated meanings. The only meaning of it I know is that when it's used with a variable inside a function, the variable keeps it's value until the end of the program and is never really re-initialized. Did I say that right? That is correct. This is called static storage duration. When you define a global variable it has external linkage by default. External linkage means that you access these variables in a different source file (actually translation unit*). The static keyword means that the variable has internal linkage and cannot be accessed in a different source file. Now please note that global variables still has static storage duration even without the static keyword. The static keywords also make free functions internal. In general, you should prefer internal linkage over external linkage. In a class scope, the static keyword means that it belongs to the class and not to the objects. For static class variables they're kinda like global variables with external linkage, and for static class methods they're kinda like friend functions. More on reddit.com
🌐 r/learnprogramming
1
1
April 15, 2021

Usually, you will see the static keyword in these places:

  1. A static variable inside a function keeps its value between invocations.
  2. A static global variable or function is "seen" only in the file in which it's declared.

(1) is the more foreign topic if you're a newbie, so here's an example:

#include <stdio.h>

void foo()
{
    int a = 10;
    static int sa = 10;
    
    a += 5;
    sa += 5;
    
    printf("a = %d, sa = %d\n", a, sa);
}


int main()
{
    int i;
    
    for (i = 0; i < 10; ++i)
        foo();
}

This prints:

a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60

This is useful for cases where a function needs to keep some state between invocations, and you don't want to use global variables. Beware, however, this feature should be used very sparingly - it makes your code not thread-safe and harder to understand.

(2) is used widely as an "access control" feature. If you have a .c file implementing some functionality, it usually exposes only a few "public" functions to users. The rest of its functions should be made static, so that the user won't be able to access them. This is encapsulation, a good practice.

Quoting Wikipedia:

In the C programming language, static is used with global variables and functions to set their scope to the containing file. In local variables, static is used to store the variable in the statically allocated memory instead of the automatically allocated memory. While the language does not dictate the implementation of either type of memory, statically allocated memory is typically reserved in data segment of the program at compile time, while the automatically allocated memory is normally implemented as a transient call stack.

See here and here for more details.

And to answer your second question, it's not like in C#.

In C++, however, static is also used to define class attributes (shared between all objects of the same class) and methods. In C there are no classes, so this feature is irrelevant.


Additionally, in C, static can be used in array declarators to specify minimum size of the array (non-function array declarators cannot use this keyword). Consider this declaration:

void func(int foo[static 42]);

The function func() takes an array of at least 42 elements.

Note that C++ does not support this use of the static keyword.

Answer from Eli Bendersky on Stack Overflow
🌐
W3Schools
w3schools.com › c › ref_keyword_static.php
C static Keyword
C Examples C Real-Life Examples ... 0; } Try it Yourself » · The static keyword allows a variable inside a function to keep its value across multiple function calls....
🌐
Wikipedia
en.wikipedia.org › wiki › Static_(keyword)
static (keyword) - Wikipedia
October 16, 2025 - C was developed as a successor of B, and the static and register keywords were added as storage class specifiers, along with auto and extern, which kept their meaning from B. However, in C, the concept of linkage for variables outside of functions was introduced.
🌐
Codecademy
codecademy.com › docs › static variables
C | Static Variables | Codecademy
April 28, 2025 - There are two main uses of the static keyword in C: to create variables with persistent values within functions, and to limit the visibility of variables or functions to a single file.
Find elsewhere
🌐
TutorialsPoint
tutorialspoint.com › cprogramming › c_static_keyword.htm
Static Keyword in C
The "static" keyword is used to declare a static variable as well as to define a static function. When declared as "static", a variable represents a static storage class. A static function is available only inside the program file (with ".c" extension) in which it is defined.
Top answer
1 of 6
21

The keyword 'static' in C has two fundamentally different meanings.

Limiting Scope

In this context, 'static' pairs up with 'extern' to control the scope of a variable or function name. Static causes the variable or function name to be available only within a single compilation unit and only available to code that exists after the declaration/definition within the compilation unit text.

This limitation itself really only means something if and only if you have more than one compilation unit in your project. If you only have one compilation unit, then it still does things but those effects are mostly pointless (unless you like digging into object files to read what the compiler generated.)

As noted, this keyword in this context pairs with the keyword 'extern', which does the opposite -- by making the variable or function name linkable with the same name found in other compilation units. So you can look at 'static' as requiring the variable or name to be found within the current unit of compilation, while 'extern' permits cross-compilation unit linkage.

Static Lifetime

Static lifetime means that the variable exists throughout the duration of the program (however long that is.) When you use 'static' to declare/define a variable within a function, it means that the variable is created sometime prior to its first usage (which means, every time I've experienced it, that the variable is created before main() starts) and isn't destroyed afterwards. Not even when the function's execution is completed and it returns to its caller. And just like static lifetime variables declared outside of functions, they are initialized at the same moment -- before main() starts -- to a semantic zero (if no initialization is provided) or to a specified explicit value, if given.

This is different from 'auto' type function variables, which are created new (or, as-if new) each time the function is entered and then are destroyed (or, as-if they were destroyed) when the function exits.

Unlike the impact of applying 'static' on a variable definition outside of a function, which directly impacts its scope, declaring a function variable (within a function body, obviously) as 'static' has no impact on its scope. The scope is determined by the fact that it was defined within a function body. Static lifetime variables defined within functions have the same scope as other 'auto' variables defined within function bodies -- function scope.

Summary

So the 'static' keyword has different contexts with what amounts to "very different meanings." The reason it was used in two ways, like this, was to avoid using another keyword. (There was a long discussion about it.) It was felt that programmers could tolerate the use and the value of avoiding yet another keyword in the language was more important (than arguments otherwise.)

(All variables declared outside of functions have static lifetime and don't need the keyword 'static' to make that true. So this kind of freed up the keyword to be used there to mean something entirely different: 'visible only in a single compilation unit.' It's a hack, of sorts.)

Specific Note

static volatile unsigned char PORTB @ 0x06;

The word 'static' here should be interpreted to mean that the linker won't attempt to match up multiple occurrences of PORTB that may be found in more than one compilation unit (assuming your code has more than one.)

It uses a special (non-portable) syntax to specify the "location" (or the label's numeric value which is usually an address) of PORTB. So the linker is given the address and doesn't need to find one for it. If you had two compilation units using this line, they'd each wind up pointing to the same place, anyway. So there's no need to label it 'extern', here.

Had they used 'extern' it might pose a problem. The linker would then be able to see (and would attempt to match up) multiple references to PORTB found in multiple compilations. If all of them specify an address like this, and the addresses are NOT the same for some reason [mistake?], then what's it supposed to do? Complain? Or? (Technically, with 'extern' the rule of thumb would be that only ONE compilation unit would specify the value and the others should not.)

It's just easier to label it as 'static', avoiding making the linker worry about conflicts, and simply put the blame for any mistakes for mis-matched addresses upon whomever changed the address to something it shouldn't be.

Either way, the variable is treated as having a 'static lifetime.' (And 'volatile'.)

A declaration is not a definition, but all definitions are declarations

In C, a definition creates an object. It also declares it. But a declaration does not usually (see bullet note below) create an object.

The following are definitions and declarations:

static int a;
static int a = 7;
extern int b = 5;
extern int f() { return 10; }

The following are not definitions, but are only declarations:

extern int b;
extern int f();

Note that the declarations do not create an actual object. They only declare the details about it, which the compiler can then use to help generate correct code and to provide warning and error messages, as appropriate.

  • Above, I say "usually," advisedly. In some cases, a declaration can create an object and is therefore promoted to a definition by the linker (never by the compiler.) So even in this rare case, the C compiler still thinks the declaration is only a declaration. It is the linker phase that makes any necessary promotions of some declaration. Keep this carefully in mind.

    In the above examples, should it turn out there are only declarations for an "extern int b;" in all the linked compilation units, then the linker is charged with the responsibility to create a definition. Be aware that this is a link-time event. The compiler is completely unaware, during compilation. It can only be determined at link-time, if a declaration of this type most be promoted.

    The compiler is aware that "static int a;" cannot be promoted by the linker at link-time, so this actually is a definition at compile-time.

2 of 6
9

statics are not visible outside of the current compilation unit, or "translation unit". This is not the same as the same file.

Notice that you include the header file into any source file where you may need the variables declared in the header. This inclusion makes the header file a part of the current translation unit and (an instance of) the variable visible inside it.

🌐
TutorialsPoint
tutorialspoint.com › cprogramming › c_static_variables.htm
Static Variables in C
To declare a static variable in C language, use the static keyword and assign the initial value.
Top answer
1 of 9
273

Variables:

static variables exist for the "lifetime" of the translation unit that it's defined in, and:

  • If it's in a namespace scope (i.e. outside of functions and classes), then it can't be accessed from any other translation unit. This is known as "internal linkage" or "static storage duration". (Don't do this in headers except for constexpr. Anything else, and you end up with a separate variable in each translation unit, which is crazy confusing)
  • If it's a variable in a function, it can't be accessed from outside of the function, just like any other local variable. (this is the local they mentioned)
  • class members have no restricted scope due to static, but can be addressed from the class as well as an instance (like std::string::npos). [Note: you can declare static members in a class, but they should usually still be defined in a translation unit (cpp file), and as such, there's only one per class]

locations as code:

static std::string namespaceScope = "Hello";
void foo() {
    static std::string functionScope= "World";
}
struct A {
   static std::string classScope = "!";
};

Before any function in a translation unit is executed (possibly after main began execution), the variables with static storage duration (namespace scope) in that translation unit will be "constant initialized" (to constexpr where possible, or zero otherwise), and then non-locals are "dynamically initialized" properly in the order they are defined in the translation unit (for things like std::string="HI"; that aren't constexpr). Finally, function-local statics will be initialized the first time execution "reaches" the line where they are declared. All static variables all destroyed in the reverse order of initialization.

The easiest way to get all this right is to make all static variables that are not constexpr initialized into function static locals, which makes sure all of your statics/globals are initialized properly when you try to use them no matter what, thus preventing the static initialization order fiasco.

T& get_global() {
    static T global = initial_value();
    return global;
}

Be careful, because when the spec says namespace-scope variables have "static storage duration" by default, they mean the "lifetime of the translation unit" bit, but that does not mean it can't be accessed outside of the file.

Functions

Significantly more straightforward, static is often used as a class member function, and only very rarely used for a free-standing function.

A static member function differs from a regular member function in that it can be called without an instance of a class, and since it has no instance, it cannot access non-static members of the class. Static variables are useful when you want to have a function for a class that definitely absolutely does not refer to any instance members, or for managing static member variables.

struct A {
    A() {++A_count;}
    A(const A&) {++A_count;}
    A(A&&) {++A_count;}
    ~A() {--A_count;}

    static int get_count() {return A_count;}
private:
    static int A_count;
}

int main() {
    A var;

    int c0 = var.get_count(); //some compilers give a warning, but it's ok.
    int c1 = A::get_count(); //normal way
}

A static free-function means that the function will not be referred to by any other translation unit, and thus the linker can ignore it entirely. This has a small number of purposes:

  • Can be used in a cpp file to guarantee that the function is never used from any other file.
  • Can be put in a header and every file will have it's own copy of the function. Not useful, since inline does pretty much the same thing.
  • Speeds up link time by reducing work
  • Can put a function with the same name in each translation unit, and they can all do different things. For instance, you could put a static void log(const char*) {} in each cpp file, and they could each all log in a different way.
2 of 9
104

In order to clarify the question, I would rather categorize the usage of 'static' keyword in three different forms:

(A). variables

(B). functions

(C). member variables/functions of classes

the explanation follows below for each of the subheadings:

(A) 'static' keyword for variables

This one can be little tricky however if explained and understood properly, it's pretty straightforward.

To explain this, first it is really useful to know about the scope, duration and linkage of variables, without which things are always difficult to see through the murky concept of static keyword

1. Scope : Determines where in the file, the variable is accessible. It can be of two types: (i) Local or Block Scope. (ii) Global Scope

2. Duration : Determines when a variable is created and destroyed. Again it's of two types: (i) Automatic Storage Duration (for variables having Local or Block scope). (ii) Static Storage Duration (for variables having Global Scope or local variables (in a function or a in a code block) with static specifier).

3. Linkage: Determines whether a variable can be accessed (or linked ) in another file. Again ( and luckily) it is of two types: (i) Internal Linkage (for variables having Block Scope and Global Scope/File Scope/Global Namespace scope) (ii) External Linkage (for variables having only for Global Scope/File Scope/Global Namespace Scope)

Let's refer an example below for a better understanding of plain global and local variables (no local variables with static storage duration) :

//main file
#include <iostream>

int global_var1; //has global scope
const global_var2(1.618); //has global scope

int main()
{
//these variables are local to the block main.
//they have automatic duration, i.e, they are created when the main() is 
//  executed and destroyed, when main goes out of scope
 int local_var1(23);
 const double local_var2(3.14);

 {
/* this is yet another block, all variables declared within this block  
 have a local scope limited within this block. */
// all variables declared within this block too have automatic duration, i.e, 
/*they are created at the point of definition within this block,
 and destroyed as soon as this block ends */
   char block_char1;
   int local_var1(32) //NOTE: this has been re-declared within the block, 
//it shadows the local_var1 declared outside

 std::cout << local_var1 <<"\n"; //prints 32

  }//end of block
  //local_var1 declared inside goes out of scope

 std::cout << local_var1 << "\n"; //prints 23

 global_var1 = 29; //global_var1 has been declared outside main (global scope)
 std::cout << global_var1 << "\n"; //prints 29
 std::cout << global_var2 << "\n"; //prints 1.618

 return 0;
}  //local_var1, local_var2 go out of scope as main ends
//global_var1, global_var2 go out of scope as the program terminates 
//(in this case program ends with end of main, so both local and global
//variables go out of scope together

Now comes the concept of Linkage. When a global variable defined in one file is intended to be used in another file, the linkage of the variable plays an important role.

The Linkage of global variables is specified by the keywords: (i) static , and, (ii) extern

( Now you get the explanation )

static keyword can be applied to variables with local and global scope, and in both cases, they mean different things. I will first explain the usage of 'static' keyword in variables with global scope ( where I also clarify the usage of keyword 'extern') and later the usage for those with local scope.

1. Static Keyword for variables with global scope

Global variables have static duration, meaning they don't go out of scope when a particular block of code (e.g main() ) in which it is used ends . Depending upon the linkage, they can be either accessed only within the same file where they are declared (for static global variable), or outside the file even outside the file in which they are declared (extern type global variables)

In the case of a global variable having extern specifier, and if this variable is being accessed outside the file in which it has been initialized, it has to be forward declared in the file where it's being used, just like a function has to be forward declared if it's definition is in a file different from where it's being used.

In contrast, if the global variable has static keyword, it cannot be used in a file outside of which it has been declared.

(see example below for clarification)

eg:

//main2.cpp
 static int global_var3 = 23;  /*static global variable, cannot be                            
                                accessed in any other file */
 extern double global_var4 = 71; /*can be accessed outside this file                  linked to main2.cpp */
 int main() { return 0; }

main3.cpp

//main3.cpp
#include <iostream>

int main()
{
   extern int gloabl_var4; /*this variable refers to the gloabal_var4
                            defined in the main2.cpp file */
  std::cout << global_var4 << "\n"; //prints 71;

  return 0;
}

now any variable in c++ can be either a const or a non-const and for each 'const-ness' we get two cases of default c++ linkage, in case none is specified:

(i) If a global variable is non-const, its linkage is extern by default, i.e, the non-const global variable can be accessed in another .cpp file by forward declaration using the extern keyword (in other words, non const global variables have external linkage ( with static duration of course)). Also, usage of extern keyword in the original file where it has been defined is redundant. In this case, to make a non-const global variable inaccessible to external file, use the specifier 'static' before the type of the variable.

(ii) If a global variable is const, its linkage is static by default, i.e a const global variable cannot be accessed in a file other than where it is defined, (in other words, const global variables have internal linkage (with static duration of course)). Also, usage of static keyword to prevent a const global variable from being accessed in another file is redundant. Here, to make a const global variable have an external linkage, use the specifier 'extern' before the type of the variable

Here's a summary of global scope variables with various linkages

//globalVariables1.cpp 

// defining uninitialized variables
int globalVar1; //  uninitialized global variable with external linkage 
static int globalVar2; // uninitialized global variable with internal linkage
const int globalVar3; // error, since const variables must be initialized upon declaration
const int globalVar4 = 23; //correct, but with static linkage (cannot be accessed outside the file where it has been declared*/
extern const double globalVar5 = 1.57; //this const variable can be accessed outside the file where it has been declared

Next, we investigate how the above global variables behave when accessed in a different file.

//using_globalVariables1.cpp (eg for the usage of global variables above)

// Forward declaration via extern keyword:
 extern int globalVar1; // correct since globalVar1 is not a const or static
 extern int globalVar2; //incorrect since globalVar2 has internal linkage
 extern const int globalVar4; /* incorrect since globalVar4 has no extern 
                         specifier, limited to internal linkage by
                         default (static specifier for const variables) */
 extern const double globalVar5; /*correct since in the previous file, it 
                           has extern specifier, no need to initialize the
                       const variable here, since it has already been
                       legitimately defined previously */
  1. Static Keyword for variables with Local Scope

Updates (August 2019) on static keyword for variables in local scope

This further can be subdivided in two categories :

(i) static keyword for variables within a function block, and (ii) static keyword for variables within an unnamed local block.

(i) static keyword for variables within a function block.

Earlier, I mentioned that variables with local scope have automatic duration, i.e they come to exist when the block is entered ( be it a normal block, be it a function block) and cease to exist when the block ends, long story short, variables with local scope have automatic duration and automatic duration variables (and objects) have no linkage meaning they are not visible outside the code block.

If static specifier is applied to a local variable within a function block, it changes the duration of the variable from automatic to static and its lifetime is the entire duration of the program which means it has a fixed memory location and its value is initialized only once prior to program start up as mentioned in cpp reference(initialization should not be confused with assignment)

lets take a look at an example.

//localVarDemo1.cpp    
 int localNextID()
{
  int tempID = 1;  //tempID created here
  return tempID++; //copy of tempID returned and tempID incremented to 2
} //tempID destroyed here, hence value of tempID lost

int newNextID()
{
  static int newID = 0;//newID has static duration, with internal linkage
  return newID++; //copy of newID returned and newID incremented by 1
}  //newID doesn't get destroyed here :-)


int main()
{
  int employeeID1 = localNextID();  //employeeID1 = 1
  int employeeID2 = localNextID();  // employeeID2 = 1 again (not desired)
  int employeeID3 = newNextID(); //employeeID3 = 0;
  int employeeID4 = newNextID(); //employeeID4 = 1;
  int employeeID5 = newNextID(); //employeeID5 = 2;
  return 0;
}

Looking at the above criterion for static local variables and static global variables, one might be tempted to ask, what the difference between them could be. While global variables are accessible at any point within the code (in the same as well as different translation units depending upon the const-ness and extern-ness), a static variable defined within a function block is not directly accessible. The variable has to be returned by the function value or reference. Lets demonstrate this by using an example:

//localVarDemo2.cpp 

//static storage duration with global scope 
//note this variable can be accessed from outside the file
//in a different compilation unit by using `extern` specifier
//which might not be desirable for certain use cases.
static int globalId = 0;

int newNextID()
{
  static int newID = 0;//newID has static duration, with internal linkage
  return newID++; //copy of newID returned and newID incremented by 1
}  //newID doesn't get destroyed here


int main()
{
    //since globalId is accessible we use it directly
  const int globalEmployee1Id = globalId++; //globalEmployeeId1 = 0;
  const int globalEmployee2Id = globalId++; //globalEmployeeId1 = 1;
  
  //const int employeeID1 = newID++; //this will lead to compilation error since newID++ is not accessible direcly. 
  int employeeID2 = newNextID(); //employeeID3 = 0;
  int employeeID2 = newNextID(); //employeeID3 = 1;

  return 0;
}

More explanation about choice of static global and static local variables could be found on this stackoverflow thread

(ii) static keyword for variables within an unnamed local block.

static variables within a local block (not a function block) cannot be accessed outside the block once the local block goes out of scope. No caveats to this rule.

    //localVarDemo3.cpp 
    int main()
    {
    
      {
          const static int static_local_scoped_variable {99};
      }//static_local_scoped_variable goes out of scope
        
      //the line below causes compilation error
      //do_something is an arbitrary function
      do_something(static_local_scoped_variable);
      return 0;
    }

C++11 introduced the keyword constexpr which guarantees the evaluation of an expression at compile time and allows the compiler to optimize the code. Now if the value of a static const variable within a scope is known at compile time, the code is optimized similarly to the one with constexpr. Here's a small example

I recommend readers also to look up the difference between constexprand static const for variables in this stackoverflow thread. this concludes my explanation for the static keyword applied to variables.

B. 'static' keyword used for functions

in terms of functions, the static keyword has a straightforward meaning. Here, it refers to linkage of the function Normally all functions declared within a cpp file have external linkage by default, i.e a function defined in one file can be used in another cpp file by forward declaration.

using a static keyword before the function declaration limits its linkage to internal , i.e a static function cannot be used within a file outside of its definition.

C. Static Keyword used for member variables and functions of classes

1. 'static' keyword for member variables of classes

I start directly with an example here

#include <iostream>

class DesignNumber
{
  private:
     
      static int m_designNum;  //design number
      int m_iteration;     // number of iterations performed for the design

  public:
    DesignNumber() {     }  //default constructor

   int  getItrNum() //get the iteration number of design
   {
      m_iteration = m_designNum++;
      return m_iteration;
   }
     static int m_anyNumber;  //public static variable
};
int DesignNumber::m_designNum = 0; // starting with design id = 0
                     // note : no need of static keyword here
                     //causes compiler error if static keyword used
int DesignNumber::m_anyNumber = 99; /* initialization of inclass public 
                                    static member  */
enter code here

int main()
{
   DesignNumber firstDesign, secondDesign, thirdDesign;
   std::cout << firstDesign.getItrNum() << "\n";  //prints 0
   std::cout << secondDesign.getItrNum() << "\n"; //prints 1
   std::cout << thirdDesign.getItrNum() << "\n";  //prints 2

   std::cout << DesignNumber::m_anyNumber++ << "\n";  /* no object
                                        associated with m_anyNumber */
   std::cout << DesignNumber::m_anyNumber++ << "\n"; //prints 100
   std::cout << DesignNumber::m_anyNumber++ << "\n"; //prints 101

   return 0;
}

In this example, the static variable m_designNum retains its value and this single private member variable (because it's static) is shared b/w all the variables of the object type DesignNumber

Also like other member variables, static member variables of a class are not associated with any class object, which is demonstrated by the printing of anyNumber in the main function

const vs non-const static member variables in class

(i) non-const class static member variables In the previous example the static members (both public and private) were non constants. ISO standard forbids non-const static members to be initialized in the class. Hence as in previous example, they must be initialized after the class definition, with the caveat that the static keyword needs to be omitted

(ii) const-static member variables of class this is straightforward and goes with the convention of other const member variable initialization, i.e the const static member variables of a class can be initialized at the point of declaration and they can be initialized at the end of the class declaration with one caveat that the keyword const needs to be added to the static member when being initialized after the class definition.

I would however, recommend to initialize the const static member variables at the point of declaration. This goes with the standard C++ convention and makes the code look cleaner

for more examples on static member variables in a class look up the following link from learncpp.com http://www.learncpp.com/cpp-tutorial/811-static-member-variables/

2. 'static' keyword for member function of classes

Just like member variables of classes can be static, so can member functions of classes. Normal member functions of classes are always associated with a object of the class type. In contrast, static member functions of a class are not associated with any object of the class, i.e they have no *this pointer.

Secondly since the static member functions of the class have no *this pointer, they can be called using the class name and scope resolution operator in the main function (ClassName::functionName(); )

Thirdly static member functions of a class can only access static member variables of a class, since non-static member variables of a class must belong to a class object.

for more examples of static member functions in a class, look up the following link from learncpp.com

http://www.learncpp.com/cpp-tutorial/812-static-member-functions/


Update April 2021: static keyword and lambda expressions

Lambda expressions follow normal name lookup rules and hence the scope (local vs global) and storage class (static vs automatic) affect how the variables are available to the lambda expressions

  1. non-static global variable is available to lambda expression within a local scope.
    //global member   
    int i=10;
    
    int main(){
        []{std::cout << i;}();
        //prints 10
    }
  1. Non-Static local variable is not available to lambda expression that appears within the same or a different scope. In this case, as we're mostly used to, the variables have to be captured by value or by reference
    int main(){
        int i{11};
        []{std::cout << i;}(); //compiler error
        [i]{std::cout << i;}(); //capture by value; correct
        //or
        [&i]{std::cout << i;}(); //capture by reference; correct
    }
  1. Static variables locally scoped static variables can be captured by lambda expressions within the same or lower/child scope
    int main(){
        static int i{12};
        []{std::cout << i;}(); //prints 12
        {
             []{std::cout << i;}();//also prints 12
        }
    }

However static variables in unnamed scope cannot be accessed outside the scope as explained previously

🌐
Quora
quora.com › What-is-the-use-of-static-keyword-in-C-1
What is the use of static keyword in C? - Quora
Answer (1 of 4): Let’s combine into one answer covering C and C++. static keyword behavior depends is it applied on global or local variables: * Global - variables outside of function, class, struct, etc. When static variable scope is limited to the file where is defined. For example if define...
🌐
cppreference.com
en.cppreference.com › w › c › keyword › static.html
C keywords: static - cppreference.com
March 6, 2023 - Log in · Page · Discussion · View · Edit · History · From cppreference.com · < c‎ | keyword · C · [edit] C language · [edit] Keywords · [edit] declarations of file scope with static storage duration and internal linkage · definitions of block scope variables with static storage duration and initialized once ·
🌐
GNU
gnu.org › software › c-intro-and-ref › manual › html_node › Static-Functions.html
Static Functions (GNU C Language Manual)
Next: Arrays as Parameters, Previous: Forward Function Declarations, Up: Function Definitions [Contents][Index] The keyword static in a function definition limits the visibility of the name to the current compilation module.
🌐
GeeksforGeeks
geeksforgeeks.org › c language › what-are-static-functions-in-c
Static Functions in C - GeeksforGeeks
July 23, 2025 - In C, functions are global by default. The static keyword before a function name makes it a static function.
🌐
Learn C
learn-c.org › en › Static
Static - Learn C - Free Interactive C Tutorial
By default, variables are local to the scope in which they are defined. Variables can be declared as static to increase their scope up to file containing them.
🌐
Upgrad
upgrad.com › home › tutorials › software & tech › static function in c
Static Function in C: Definition, Examples & Best Practices
April 3, 2025 - This prevents the function from being accessed by code in other files, even if they are part of the same project. The static keyword, when applied to functions, is a way to encapsulate the functionality and prevent it from being exposed globally.
🌐
Codidact
software.codidact.com › posts › 285050
What does the static keyword do in C? - Software Development
Most importantly, static variables in a function hold their value from one call to the next. The use of the static keyword for parameters is just "we need a keyword, and don't want to introduce a new one." It basically says "the pointer being passed is not null, and points to at least this much storage."