Search

4.3a — Scope, duration, and linkage summary

The concepts of scope, duration, and linkage cause a lot of confusion, so we’re going to take an extra lesson to summarize everything.

Scope summary

A identifier’s scope determines where it is accessible. An identifier that is out of scope can not be accessed.

  • Variables with block scope / local scope can only be accessed within the block in which they are declared. This includes:
    • Local variables
    • Function parameters
  • Variables with global scope / file scope can be accessed anywhere in the file. This includes:
    • Global variables

Duration summary

A variable’s duration determines when it is created and destroyed.

  • Variables with automatic duration are created at the point of definition, and destroyed when the block they are part of is exited. This includes:
    • Normal local variables
  • Variables with static duration are created when the program begins and destroyed when the program ends. This includes:
    • Global variables
    • Static local variables
  • Variables with dynamic duration are created and destroyed by programmer request. This includes:
    • Dynamically allocated variables (we’ll talk about these when we cover dynamic allocation in chapter 6)

Linkage summary

An identifier’s linkage determines whether multiple instances of an identifier refer to the same identifier or not.

  • Identifiers with no linkage mean the identifier only refers to itself. This includes:
    • Normal local variables
    • User-defined types, such as enums, typedefs, and classes declared inside a block (we’ll cover these in later lessons).
  • Identifiers with internal linkage can be accessed anywhere within the file it is declared. This includes:
    • Static global variables (initialized or uninitialized)
    • Const global variables
    • Static functions (we’ll cover these in chapter 7)
  • Identifiers with external linkage can be accessed anywhere within the file it is declared, or other files (via a forward declaration). This includes:
    • Normal functions
    • Non-const global variables (initialized or uninitialized)
    • Extern const global variables
    • User-defined types, such as enums, typedefs, and classes declared in the global scope (we’ll cover these in later lessons).

Identifiers with external linkage will cause a duplicate definition linker error if the definitions are compiled into more than one .cpp file.

There are a few things worth explicitly noting here. First, functions are extern by default, and can be made internal by using the static keyword.

Second, astute readers may note that global types have external linkage, but their definitions don’t cause a linker error when included in multiple files. This is because types, templates, and extern inline functions have an exemption that allows them to be defined in more than one file, so long as the definitions are identical. Otherwise, they wouldn’t be of much use.

Variable scope, duration, and linkage summary

Because variables have scope, duration, and linkage, let’s summarize in a chart:

Type Example Scope Duration Linkage Notes
Local variable int x; Block scope Automatic duration No linkage
Static local variable static int x; Block scope Static duration No linkage
Dynamic variable int *x = new int; Block scope Dynamic duration No linkage
Function parameter void foo(int x) Block scope Automatic duration No linkage
External non-const global variable int g_x; File scope Static duration External linkage Initialized or uninitialized
Internal non-const global variable static int g_x; File scope Static duration Internal linkage Initialized or uninitialized
Internal const global variable const int g_x(1); File scope Static duration Internal linkage Must be initialized
External const global variable extern const int g_x(1); File scope Static duration External linkage Must be initialized

Forward declaration summary

You can use a forward declaration to access a function or variable in another file:

Type Example Notes
Function forward declaration void foo(int x); Prototype only, no function body
Non-const global variable forward declaration extern int g_x; Must be uninitialized
Const global variable forward declaration extern const int g_x; Must be uninitialized
4.3b -- Namespaces
Index
4.3 -- Static duration variables

22 comments to 4.3a — Scope, duration, and linkage summary

  • Got cleared all of my former doubts…Bro Thankyou so much for this awsome site…

  • Robert Hannah

    Wow. I was literally just about to write some kind of summary like this to supplement notes I’ve taken from your website. Thanks! I’ve been using this site for years: Perhaps the best non-book resource that there is on C++.

  • Hi, I have one doubt.
    is it possible to access a static local variable in a function from the main function. if it possible to access, then that data is safe or not?

    • Alex

      No, it is not possible (at least not directly). Static local variables are only visible within the function in which they are declared.

  • Hi Alex,
    Thanks a lot for the replay

    I tried indirectly, Like address of a static local variable assigned to a global pointer and deferred at another function. Compiler not showing any error and I am getting the expected result as well. As per my knowledge the lime time of the static local variable till up to the end of the program ,  is it correct? then why can’t access the local static variable outside that function(indirectly)? is any risk involved in this way like data overwriting?

    • Alex

      Yes, the lifetime of a local static variable is until the end of the program. But the scope of a local static variable is still only within the function in which it is declared, the same as a local non-static variable. The scope governs where you can access the variable, which is why you can’t use it directly outside the function.

      You can access the variable outside the function indirectly (via a pointer or reference), but even though you can do this, it’s not advised.

  • Thanks Alex,
    I need to clear one more thing, Consider I have 2 Task  and I called a common function from both the task which having a static local variable , So from one task I am accessing and set one value to that static variable, and through another task I read that value. So In both case am accessing the same local static variable. My doubt is ,am accessing the same memory ? able to consider that variable as a shared variable or shared memory?

    • Alex

      In both cases, you’re accessing the same local static variable, which uses the same memory. It’s not really shared memory -- it’s just a variable that you can access whenever you’re inside the function (doesn’t matter which function it was called from).

      • Hi Alex

        Why it’s not shared memory? As per my knowledge shared memory is the memory in which a common memory get accessed from 2 different task, is it correct ?  Would you please give me the definition of Shared memory?

        • Alex

          Maybe I’m misunderstanding what you mean by task. If by task you mean “process” or “thread” (or anything else that can run in parallel), then yes, the memory would be shared.

          • Yes, I meant Task as two separate Process that may or may not be run parallel.

            Now everything is clear

            Thanks Alex.

            The effort you put in this site is really worth for learner

  • kris

    This is very helpful. Thank you

  • Matt

    In section "Duration summary", the listings for automatic duration and static duration (local variables) should be updated to reflect that the variables are created during definition, not when the block is entered.

  • John

    Can you please explain how "Extern const global variable"  has external linkage ? can we access any variable defined as const in other file without using namespace?

    a.cxx:
    extern const int a(5);

    b.cxx:

    extern const int a;
    int main(){
        std::cout << a << std::endl;
    }

    It gives an error as “b.cxx:(.text+0x6): undefined reference to `a’ “

  • nikos-13

    " (initialized or uninitialized) "

    Why do you use this prenthesis

  • Nguyen

    Hi Alex,

    I don’t understand the second row (Static local variable) in the chart.

    Example:  static int x;
    Scope:    Block scope
    Duration: Static duration
    Linkage:  No linkage
    Note:  

    I believe "Static Local Variable" is covered in the very last section 4.3.  

    I think "Static Local Variable" has Static duration if I both define a variable AND give it an initial value in the same step(for example: static int x = 1;).  

    In the above example, x is not initialized.  I am not sure if x has Static or automatic duration? If x has static duration then why the output of the following code is different from another?

    #include <iostream>

    void incrementAndPrint()
    {
        using namespace std;
        static int s_value = 0; // static duration variable initialized
        ++s_value;
        cout << s_value << endl;
    }

    int main()
    {
        incrementAndPrint();
        incrementAndPrint();
        incrementAndPrint();

        return 0;    
    }

    Which outputs:

    1
    2
    3

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

    #include <iostream>

    void incrementAndPrint()
    {
        using namespace std;
        static int s_value; // static duration variable declared
        s_value = 0; // static duration variable assigned
        ++s_value;
        cout << s_value << endl;
    }

    int main()
    {
        incrementAndPrint();
        incrementAndPrint();
        incrementAndPrint();

        return 0;    
    }

    Which outputs:

    1
    1
    1

    • Alex

      Static variables have static duration regardless of whether you initialize them or not. In your example, you’re not initializing the static (which would only happen once, when the static is created). Instead, you’re assigning a value to the static variable, which happens every time the function runs. So even though your static s_value is keeping its value between function calls, you’re resetting it back to 0 via assignment every function call.

      This is why we typically initialize static variables, not assign values to them.

  • Varun

    Give the man a knighthood.

Leave a Comment

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