2010-06-06

C++: The static keyword (clarification)

The static keyword can have three different meaning depending on the context.

Static function or variable

The variable or function name will not be propagated for the linker, that means that this variable or function will be available only in it's compilation unit. This feature is rarely used, only if we want to hide something explicitly from other compilation units.
static int MySecretFunction(){ /* ... */ }
static int MY_SECRET_VARIABLE = 7; // You should give a starting value

Static variable in a function

int Summarize(int next)
{
    static int sum = 0;
    sum += next;
    return sum
}
The static variable in a function is initialized at the first time when the function is called. WARNING: Using this feature is not thread-safe in C++. In C++0x you will have the opportunity to write
thread_local static int sum = 0;
which creates a global variable in the function's scope for each thread.

Static class members

Class member functions (methods) can be static or non-static. Non-static members are bound to the objects of the class, static members are not bound to the objects but are somehow related to the class. Study example:
// matrix.h:
class Matrix {
public:
    Matrix(int n_, int m_); // Constructor
    Matrix& MultiplyByNumber(double lambda); // Non-static member function
    static Matrix CreateIdentityMatrix(int n); // Static member function
    // ...
private:
    int n,m; // Non static emember variables
    double *pData; // Non static member variable
    static int serial; // Static member variable
};
// matrix.cpp:
int Matrix::serial = 0;
// ...
Note: You have to provide explicit storage place for the static member variables, that means you have to choose a compilation unit (.cpp file), where you write int Matrix::serial = 0;.
Non-static (or object-) methods can access both static and non-static member functions and variables. Static methods can access only static members. (And of course non-static members of the objects that are around.)

Simple global variables and initialization

// gadget.h:
extern int dontUseGlobalVariablesIfPossible; // "Propagation" in the .h file
// gadget.cpp:
int dontUseGlobalVariablesIfPossible = 0; // Storage place
The initialization of variables in static storage class (simple global variables, static variables, static member variables, but not function's static variables) are done in the order that they are presented inside the compilation unit (see exception below). The order of initialization of two variables in different compilation units is undefined.
The important exception is that primitive types (int, char, pointer, float, double, ...) are initialized upon loading if they are initialized with literals.
int x = 0; // Load time, practically before "everything"
int y = f(); // Simply before main() based on the rules above.

No comments:

Post a Comment