Search

4.3 — Static duration variables

The static keyword is one of the most confusing keywords in the C++ language (maybe with the exception of the keyword “class”). This is because it has different meanings depending on where it is used.

In section 4.2 -- Global variables, you learned that when applied to a variable declared outside of a block, it defines a global variable with internal linkage, meaning the variable could only be used in the file in which it was defined.

The static keyword can also be applied to variables declared inside a block, where it has a different meaning entirely. In section 4.1a -- Local variables and local scope, you learned that local variables have automatic duration, which means they are created when the block is entered, and destroyed when the block is exited.

Using the static keyword on local variables changes them from automatic duration to static duration (also called fixed duration). A static duration variable (also called a “static variable”) is one that retains its value even after the scope in which it has been created has been exited! Static duration variables are only created (and initialized) once, and then they are persisted throughout the life of the program.

The easiest way to show the difference between automatic and static duration variables is by example.

Automatic duration (default):

Each time incrementAndPrint is called, a variable named value is created and assigned the value of 1. incrementAndPrint increments value to 2, and then prints the value of 2. When incrementAndPrint is finished running, the variable goes out of scope and is destroyed. Consequently, this program outputs:

2
2
2

Now consider the static scope version of this program. The only difference between this and the above program is that we’ve changed the local variable value from automatic to static duration by using the static keyword.

Static duration (using static keyword):

In this program, because s_value has been declared as static, s_value is only created and initialized (to 1) once. When it goes out of scope, it is not destroyed. Each time the function incrementAndPrint() is called, the value of s_value is whatever we left it at previously. Consequently, this program outputs:

2
3
4

Just like we use “g_” to prefix global variables, it’s common to use “s_” to prefix static (static duration) variables. Note that internal linkage global variables (also declared using the static keyword) get a “g_”, not a “s_”.

One of the most common uses for static duration local variables is for unique identifier generators. When dealing with a large number of similar objects within a program, it is often useful to assign each one a unique ID number so they can be identified. This is very easy to do with a static duration local variable:

The first time this function is called, it returns 0. The second time, it returns 1. Each time it is called, it returns a number one higher than the previous time it was called. You can assign these numbers as unique IDs for your objects. Because s_itemID is a local variable, it can not be “tampered with” by other functions.

Static variables offer some of the benefit of global variables (they don’t get destroyed until the end of the program) while limiting their visibility to block scope. This makes them much safer for use than global variables.

Quiz

1) What effect does using keyword “static” have on a global variable? What effect does it have on a local variable?

Quiz Answers

1) Show Solution

4.3a -- Scope, duration, and linkage summary
Index
4.2a -- Why global variables are evil

65 comments to 4.3 — Static duration variables

  • carmen

    well .. if they become inaccessible … what’s the point? We can’t use them anyway … can we?

    • You can’t use them when they’re inaccessible, but you can use them if and when they do become accessible again. For example, each time IncrementAndPrint() is called, s_nValue comes back into scope with it’s previous value. This allows you to have a variable that keeps track of it’s value between calls without exposing that variable to other functions (which is dangerous, because they might change it).

    • MrAlshahawy

      Consider Static variable as a combination between Global and Local Variables benefits:

      Static takes the benefit of keeping its value after you go out of the scope just like Global, At the same time you avoid the downside of Global variable which is that any other functions may change its value causing unpredictable values.

    • jon

      Also, since it is only declared once and not every time the function is called, it conserves memory. Right?

      • Alex

        No.

        A static int and a local int both may take 4 bytes while in memory. But the static int takes up that 4 bytes for the whole duration of the program, whereas the local variable takes up that 4 bytes only while the code is in the block where the local variable is defined.

  • Hertz

    Helped me a lot to understand the static keyword. The explanation is very clear and useful. Thanks.

  • Niaz

    Hey Alex thank your very much. I got my concpet cleared not only about STATIC variable but other complex things such as Variable Passing Machanisam.

    Thanks
    Niaz

  • Alfreda

    They really thought of everything when they made C/++ programming language didn’t they? O_O

  • mens sana in corpore sano

    Hi Alex, you have great tutorial! I have one question, when working with multiple file:

    Is there any different for the usage when im declaring file scope variable without static like code below? As my understanding, within this way nValue will be compiled as file scope variable. Am I right?

    Thanks!

    • Xanth

      The way you have it written out the second time declares it as a global variable. From my understanding even if it’s in a different file, it still has a global scope if it’s declared outside of a block without the static keyword.

    • Alex

      In the first case, nValue has internal linkage, so it could only be used in the file in which it is defined.

      In the second case, nValue has external linkage, so it could be used in other files (via a variable forward declaration).

  • Freyr

    If I make a multi-file program e.g. main.cpp, source1.cpp, source1.h and then apart from declaring functions in source1.h, I also declare some variables. If source1.h is included in main.cpp and source1.cpp, in which scope are the variables found? Are they global?

    • Falcon

      Yes these variables will be having global scope. If you are declaring variables in source1.h they should be preceded with “extern” keyword.

  • konda reddy

    excellent tutorial for static variable concept.
    thanks Alex.

  • Brad

    I assume static variables reset every time the program is exited? Is there a way to keep a variables value even after the program ends? Say for instance you wanted to create a counter that keeps up with how many time a program was run or a particular function was called?

    • Tom

      Brad -

      The easiest way would be to write the variable to a file at the end of the program, then read it back in again when the program is next run.

      • Alex

        Static variables do get destroyed when the program is exited, so when you restart your program, they will be created anew.

        If you want to persist your variables beyond the scope of your entire program, you’ll need to write them to external storage. The two most common options here are writing them to a file, or to a database.

  • Alex, thank you for this excellent tutorial! Great explanation of what is otherwise quite a tricky set of concepts.

  • George

    Great tutorial! Thanks a lot 🙂

  • Jay

    Hey this is a great tutorial on the “static” keyword. I am also interested in the application for the use of static inside a class definition in another file as well. for instance :

    Just wondering when using static variables in the scope of a class definition in another file "MyClass.h", if not how would someone go about using these type of variables.. Thanks for the help !!

  • Elpops

    First, i thank you for this excellent website where anyone can learn c++ for free with great explanations (y).

    I have a question about this example :

    void IncrementAndPrint()
    {
        using namespace std;
        static int s_nValue = 1; // fixed duration
        ++s_nValue;
        cout << s_nValue << endl;
    } // s_nValue is not destroyed here, but becomes inaccessible

    int main()
    {
        IncrementAndPrint();
        IncrementAndPrint();
        IncrementAndPrint();
    }

    When incrementAndPrint is first called, i agree that it prints the value 2 for s_nvalue, but when it’s called the second time, the second line of incrementAndPrint decalaration states "static int s_nValue = 1;", so the value of s_nvalue should be modified to 1, and the function should return the same value as earlier : 2.

    It’s like this line of the function declaration has been obliterated when it’s been called the 2nd time.

    Why isn’t it like i think it has to be ? i’ll appreciate your help with this situation 😀 !

    • Alex

      Good question. The static variable definition line is only executed once -- that means our initialization is also only executed once.

  • Anon

    I don’t get it.

    Why does it print 0? I added the variable s_ItemID to watch, and debugged the program with a step into. At:

    the value of s_itemID changes to 1, but it still prints 0.

    • Alex

      s_itemID++ uses the postfix version of ++, which evaluates to a value and THEN increments.

      So stepping through what happens:
      * s_itemID is initialized with value 0.
      * The value of s_itemID (0) is temporarily set aside. The ++ operator increments s_itemID to 1. Then the set aside value of 0 is returned to the caller.
      * The std::cout line prints the return value of 0.

      If we’d changed line 4 to be “return ++s_itemID;” instead, it would have returned 1, because in that case, the value of s_itemID is incremented before it’s returned rather than after.

  • termor

    Next lesson link wrong, must be namespaces.
    Thanx for excellent lessons!

  • Todd

    Typo.

    "Note that internal linkage global variables (also declared using the static keyword get a “g_”, not a “s_”)." (move the end parentheses to directly after "keyword")

    BTW, your second paragraph is very well-written. Great recap!

  • Elpidius

    You’ve mentioned that a static duration variable is only created once.

    I’ve realized that it is better to initialize a static variable, than to declare the variable and then assign a value to it later. If you do the latter, then going back into scope of the static duration variable a second (and subsequent) time won’t declare the variable again, but it will assign the same value to it again, thereby inhibiting the value from incrementing by 1 each time we enter that static variable’s scope. I’ve placed examples below of what I mean.

    Initializing a static duration variable:

    Which outputs:

    Declaring a static duration variable, then assigning a literal to it:

    Which outputs:

  • hussein

    Typo:
    The static keyword is one of the "more" confusing "keyword" in the C++ language

    the correct one:
    The static keyword is one of the "MOST" confusing "keywordS" in the C++ language

  • shawn

    Sir,
    If we define the same static variable in two user functions but initialize the two identical variables to different values inside the respective functions would this give an error as static can be declared once only? and this error would be at time of compilation or at the time when i run the programme and use this member variable?
    Thnx

    • Alex

      This would not cause a problem, as the static variables with identical names in different functions are never both accessible in the same scope.

      This is something you could have just answered for yourself in a compiler. 🙂

  • shawn

    Okay thnx sir . Yeah I could have figured it out myself . -__-

  • Helvetica Standard

    Hah, strange that they used the static keyword both for declaring a global variable with internal linkage and a local variable with static duration. Could have used "intern" or something with internal linkage, as opposed to "extern" for external linkage.

  • Lokesh

    I guess
    "it’s common to use “s_” to prefix static (static scope) variables"
    should be
    "it’s common to use “s_” to prefix static (static duration) variables"

  • Shiva

    The static keyword may be one of the most confusing keywords in the C++ language, but the explanation is so clear that I had to read it only once. May be that’s because it came after the brainstorming dynamic-variables stuff. Great job anyways, Alex! 🙂

  • Jim

    Alex,
    So it wouldn’t be a good idea to call a static variable inside a block,
    static const int s_value = 1;
    although the variable is created only once and you say it retains that value of (1) if used again during the program.  How can s_value still be incremented in that block?

    Why doesn’t the compiler squawk when ++s_value is incremented. Or is static int s_value=1; somehow masked from the increment?  Can s _value be changed again further in the program? This is kind of confusing.

    • Alex

      s_value is initialized with the value of 1, and can thereafter be used like a normal variable inside the block in which it is declared. In this context, the static keyword basically tells the variable “don’t die when you go out of scope”, so if that block is re-entered later, the variable (with whatever value it had previously) is still there and can be used like normal.

  • Dmitry M

    Hi Alex!

    First of all: thank you for great tutorial!

    A-a-and I want to help you to make it a bit better

    I think, it’s better to remind about postfix incrementation, which means that ID is returned first and THEN it incremented. I was a confused for a minute 🙂

    P.S. Sorry for bad english.

  • Jim

    Alex,
    So what your basically saying in this lesson. Is that a static variables should be used any where you want to retain a value after a block is closed. Then reuse that retained value again when that block is again recalled in the program. True?

    You could decrement the static variable value too. True?

    I would think you might use a static variable to keep track of any type of record numbers like you did with the itemID. Check numbers etc.. True?

    The static variable is destroyed at the end of the program. True?

  • Jim

    Alex,
    One more dumb question. Where might I find a list/chart of how long different(types of)variables last in C++, if there is such a list? Or a link to one?

    For instance I already know a local variable have block duration and begins and ends within the curly brackets. By types of I mean local, global, static, const, etc..

    This type of list or chart might be useful for other newbees if we can find one.

  • John

    Alex,
    Is there a way to "destroy" a static variable inside a block after I’m done with it?
    Example, if I want to use incrementNum(); 5 times only, after the 5th time, destroy the static variable inside instead of keeping it in memory until the program is ended?

    • Alex

      Not really. If you want to control when the duration of a variable ends, you should declare it as a dynamic variable so you can explicitly delete it.

  • Sanja

    In the static example how the compiler doesn’t complain about redeclaration of the s-value variable and why thst line is executed only once.

    • Alex

      Static variables are initialized (once) at the point of definition, and are not destroyed until the end of the program.

      The compiler won’t complain about redeclaration because it’s only declared once (if the variable were non-static, the compiler wouldn’t complain either).

      The initializer is only executed once because static variables are only initialized once. Subsequent initializations are skipped -- otherwise you’d end up resetting your static value back to the initialized value every time the function was called, which wouldn’t be of much use (if you want to do that, you can just assign a value to it).

  • Olvin Lizama

    Hi Alex,

    On my Logic I don’t get it how is possible that declaring a local variable as static will remain it’s value, let me see your code.

    In this code you are declaring static int s_value = 1; my logic tells me that each time you call this function, the variable will be declared and assigned the value of 1, unless C++ doesn’t declare a variable that is already declared or (Could you tell me what’s Happening???)

    But I think this will be a different behavior,

    So this program will Print:

    2
    2
    2

    Regards,

    • Alex

      Static variables only get initialized once, so even though the definition is encountered again, the initialization doesn’t happen again.
      In your second example, since you’re doing an assignment, that will execute every time the function runs so your expected output is correct.

  • Ion

    I modified the function incrementAndPrint:

    The result is: 1, 1, 1, isn’t "t" supposed to preserve it’s value?

    • Ion

      I am more used to Pascal language, and I expected "t" to be incremented.
      I think the answer is: incrementAndPrint is used with the value 0, and it increments it by 1, it returns 1 but that return is never used. It does not return the variable "t".

      What can I do for the function to modify “t”, can I do something else than making “t” a global variable?

      • Alex

        You can do a few things:
        1) Make t a global variable (don’t do this).
        2) Assign the return value of incrementAndPrint() back to t.
        3) Make function parameter x a reference parameter instead of a value parameter. We cover this in lesson 7.3. You could skip there now if you’re interested in reading that ahead of time.

    • Alex

      A few things:
      1) Making t static isn’t doing anything useful here, since main() never goes out of scope until the program ends. There’s no value that needs to be preserved.
      2) When you pass t to function incrementAndPrint(), the value of t is copied into parameter x. Thus function incrementAndPrint() is actually incrementing a copy of t, not t itself. Thus the value of t is not being changed.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter