English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C++ Storage class

C ++Each variable in has two characteristics: type and storage class.

Type specification indicates the data type that can be stored in a variable. For example: int, float, char, etc.

And, the storage class controls two different properties of variables: lifetime (determining how long a variable can exist) and scope (determining which part of the program can access it).

Storage class defines C++ Variables in the program/The scope (visibility) and lifetime of functions. These specifiers are placed before the types they modify. The following lists C++ Storage classes available in the program:

  • auto

  • register

  • static

  • extern

  • mutable

  • thread_local (C++11)

From C++ 17 Starting, the 'auto' keyword is no longer in C++ Storage class specifier, and the register keyword is deprecated.

auto storage class

from C++ 11 sinceauto keyword is used for two cases: to infer the type of the variable from the initialization expression when declaring a variable, and as a placeholder for the return value of a function when declaring a function.

C++98The auto keyword in the standard is used for the declaration of automatic variables, but due to its rare and redundant use, in C++11This usage has been removed from the standard.

The type of the declared variable is automatically inferred from the initialization expression, as follows:

auto f=3.14;      //double
auto s("hello");  //const char*
auto z = new auto(9); // int*
auto x1 = 5, x2 = 5.0, x3='r';//Error, must be initialized to the same type

Register storage class

register Storage class is used to define local variables that are stored in registers rather than RAM. This means that the maximum size of the variable is equal to the size of the register (usually a word), and unary '&' operator cannot be applied to it (because it has no memory location).

{
   register int miles;
}

The register is used only for variables that require fast access, such as counters. It should also be noted that defining 'register' does not mean that the variable will be stored in a register; it means that the variable may be stored in a register, depending on hardware and implementation limitations.

Static storage class

static Storage class indicates to the compiler that the local variable should exist throughout the life of the program, without needing to be created and destroyed each time it enters and leaves scope. Therefore, using static to modify local variables can maintain the value of the local variable between function calls.

The static modifier can also be applied to global variables. When static is used to modify a global variable, it limits the scope of the variable to the file in which it is declared.

In C++ In C, when the static modifier is used on class data members, it causes only one copy of the member to be shared among all objects of the class.

#include <iostream>
 
// Function declaration 
void func(void);
 
static int count = 25; /* Global variable */
 
int main()
{
    while(count--)
    {
       func();
    }
    return 0;
}
// Function definition
void func(void)
{
    static int i = 8; // Local static variable
    i++;
    std::cout << "variable i is " << i;
    std::cout << " , variable count is " << count << std::endl;
}

When the above code is compiled and executed, it will produce the following result:

, variable i is 9 , variable count is 24
, variable i is 10 , variable count is 23
, variable i is 11 , variable count is 22
, variable i is 12 , variable count is 21
, variable i is 13 , variable count is 20
, variable i is 14 , variable count is 19
, variable i is 15 , variable count is 18
, variable i is 16 , variable count is 17
, variable i is 17 , variable count is 16
, variable i is 18 , variable count is 15
, variable i is 19 , variable count is 14
, variable i is 20, variable count is 13
, variable i is 21 , variable count is 12
, variable i is 22 , variable count is 11
, variable i is 23 , variable count is 10
, variable i is 24 , variable count is 9
, variable i is 25 , variable count is 8
, variable i is 26 , variable count is 7
, variable i is 27 , variable count is 6
, variable i is 28 , variable count is 5
, variable i is 29 , variable count is 4
, variable i is 30, variable count is 3
, variable i is 31 , variable count is 2
, variable i is 32 , variable count is 1
, variable i is 33 , variable count is 0

extern storage class

extern The storage class is used to provide a reference to a global variable, which is visible to all program files. When you use 'extern', for variables that cannot be initialized, it will point the variable name to a previously defined storage location.

When you have multiple files and define a global variable or function that can be used in other files, you can use extern To get a reference to a defined variable or function.extern It is used to declare a global variable or function in another file.

The extern modifier is typically used when there are two or more files sharing the same global variable or function, as shown below:

First file: main.cpp

#include <iostream>
 
int count ;
extern void write_extern();
 
int main()
{
   count = 5;
   write_extern();
}

Second file: support.cpp

#include <iostream>
 
extern int count;
 
void write_extern(void)
{
   std::cout << "Count is " << count << std::endl;
}

Here, the second file contains extern The keyword is used to declare a variable that has already been defined in the first file main.cpp. Now, compile these two files as follows:

$ g++ main.cpp support.cpp -o write

This will produce write An executable program, try to execute writeIt will produce the following result:

$ ./write
Count is 5

mutable storage class

mutable The specifier is only applicable to class objects, which will be explained at the end of this tutorial. It allows object members to replace constants. That is, mutable members can be modified by const member functions.

thread_local storage class

Variables declared with the thread_local specifier can only be accessed on the thread they were created on. Variables are created when the thread is created and destroyed when the thread is destroyed. Each thread has its own copy of the variable.

The thread_local specifier can be combined with static or extern.

thread_local can only be applied to data declarations and definitions, thread_local cannot be used for function declarations or definitions.

The following demonstrates variables that can be declared as thread_local:

thread_local int x;  // Global Variables Under a Namespace
class X
{
    static thread_local std::string s; // Static Member Variables of a Class
};
static thread_local std::string X::s;  // X::s is to be defined
 
void foo()
{
    thread_local std::vector<int> v;  // Local Variables
}