Storage Specifiers
Both global and local variables can have static
or threadlocal
storage specifiers. static
means that the memory for variable is allocated at the program start and it stays there until the program terminates. threadlocal
on the other hand, means that variable is allocated from the thread local storage – each thread in program has its own copy of such variable. To avoid unnecessary performance penalties during thread start, two limitations are imposed on threadlocal
variables. The first limitation is: thread variables cannot have initializers; the second – thread variables cannot be aggregate (e.g. class, struct, array etc).
Now, what if you do need an aggregate thead variable and/or a thread variable which needs to be initilized? The answer is simple – use pointers:
threadlocal MyClass* threadClass;
// ...
if (!threadClass)
threadClass = new MyClass (10, 20, 30);
There is one more storage class, which actually cannot be explicitly expressed with storage specifier – local
storage. The actual memory for local storage can come from stack or from GC-heap, but the most important thing about local storage is this: every time intruction pointer goes through a variable declaration, this will be a new copy of the local variable.
If storage specifier is omitted, then global variables get assigned static
storage class and local variables – local
storage class.
Member fields of classes, structs and unions can have both static
and threadlocal
storage specifiers – the meaning of these are identical to what we have just discussed. Member fields can also have mutable
storage specifier, which means that this member field can be modified using const
pointer to the parent class/struct/union – just like in C/C++.
Now let’s talk about functions. Global functions always have static
storage class. Member functions, on the other hand, can have the following storage specifiers:
static
virtual
abstract
override
static
in respect to member functions mean that this function does not accept implict this
argument. Therefore, static functions cannot access any non-static member fileds. virtual
, abstract
and override
specifiers allow programmer to create virtual functions – i.e. the functions which can be overriden in derived classes. Note that neither structs nor unions are not allowed to have virtual functions, only classes do.