Saturday, July 23, 2011

Storage Class Specifiers and Name Scope in C++

The following is part of a contribution I made to one of the pages on the
Qt Centre Community Wiki, titled "Going Out of Scope":


In C++, as in many other languages, variables have scope; i.e., a variable or function name can be used only within certain parts of a program. This "area of visibility" is referred to as the name's scope. Additionally, C and C++ also employ the concepts storage duration and linkage. Storage duration determines how and when during program execution an identifier exists in memory – the lifetime of its storage. Linkage affects a name's visibility across translation units (the contents of a single source file, plus the contents of any header files included by it).

The two concepts that are most relevant here are scope and storage duration.

The different types of scope in C++ are:
  • Function scope: Applies only to labels, and is the same as in C.
  • Function prototype scope: Applies to names declared in the parameter list of a function declaration, unless it is also a definition.
  • Local scope: This is the scope of names declared within a block (a section of code enclosed by braces { ... } ). Variables with local scope are referred to as local variables.
  • Namespace scope: Namespaces in C++ are groups of classes, objects and functions. A name that is declared outside of any function, structure, or union declaration has namespace scope. Also known as "global scope".
  • Class scope: Applies to names declared within the body of a class definition. This is the scope given to class members.

Local variables

Local variables have local scope, automatic storage by default, and no linkage. Automatic variables are stored on the program's call stack (see below for a discussion on the terms stack and heap).
void foo()
{
    int n = 1;
}
Here, n is visible only within the scope of foo(), and its storage ends when the process exits the function – when "n is falling out of scope".

A local variable declared with the static keyword has local scope, static storage, and no linkage.
void foo()
{
    static int n = 1;
}
In this case, n is still only visible within the function foo(), but allocated and initialized at the beginning of program execution (only once). Its storage continues to exist throughout the program, regardless of whether it is in scope or not.

Dynamic storage duration

Dynamic variables are allocated at runtime from a pool of memory called the heap, using the operators new and new[].
void foo()
{
    int *n = new int;

    // ...

    delete n;
}

Class members

Class members have class scope, they are similar to local variables in that they have automatic storage by default. The same rules for the static keyword and dynamic memory allocation also applies.
class Bar
{
    int n;
}

Bar *bar = new Bar;
In the above example, n has class scope and automatic storage, its memory is being allocated and freed along with the object holding the variable.

Stack and Heap

The terms stack and heap are mentioned quite often in C++ contexts. They are however more related to how the compiler implements memory allocation, and not so much the language itself. In fact, the C++ Standard does not use the terms "heap" and "stack", i.e., the Standard doesn't mandate how the compiler implements memory allocation in terms of where memory is being allocated, and as shown in previous example, automatic storage is not always synonymous with stack allocation.

0 comments:

Post a Comment