Yes, all members are initialized for objects with static storage. See 6.7.8/10 in the C99 Standard (PDF document)
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these rules.
To initialize everything in an object, whether it's static or not, to 0, I like to use the universal zero initializer
sometype identifier0 = {0};
someothertype identifier1[SOMESIZE] = {0};
anytype identifier2[SIZE1][SIZE2][SIZE3] = {0};
There is no partial initialization in C. An object either is fully initialized (to 0 of the right kind in the absence of a different value) or not initialized at all.
If you want partial initialization, you can't initialize to begin with.
int a[2]; // uninitialized
int b[2] = {42}; // b[0] == 42; b[1] == 0;
a[0] = -1; // reading a[1] invokes UB
Answer from pmg on Stack OverflowYes, all members are initialized for objects with static storage. See 6.7.8/10 in the C99 Standard (PDF document)
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these rules.
To initialize everything in an object, whether it's static or not, to 0, I like to use the universal zero initializer
sometype identifier0 = {0};
someothertype identifier1[SOMESIZE] = {0};
anytype identifier2[SIZE1][SIZE2][SIZE3] = {0};
There is no partial initialization in C. An object either is fully initialized (to 0 of the right kind in the absence of a different value) or not initialized at all.
If you want partial initialization, you can't initialize to begin with.
int a[2]; // uninitialized
int b[2] = {42}; // b[0] == 42; b[1] == 0;
a[0] = -1; // reading a[1] invokes UB
Yes, they are, as long they have static or thread storage duration.
C11 (n1570), § 6.7.9 Initialization #10
If an object that has static or thread storage duration is not initialized explicitly, then:
[...]
- if it has arithmetic type, it is initialized to (positive or unsigned) zero;
- if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
[...]
The following code:
#include <stdio.h>
#define SIZE 5
unsigned fun();
void sod(unsigned*, unsigned);
void main()
{
unsigned arr[SIZE], i
;
sod(arr, SIZE);
for (i = 0; i < SIZE; i++)
printf("%u ", arr[i]);
}
unsigned fun()
{
static unsigned value = 0;
value = !value ? 1 : value << 1;
value = !value ? 1 : value;
return value;
}
void sod(unsigned* arr, unsigned n)
{
unsigned i;
for (i = 0; i < n; i++)
arr[i] = fun();
}Outputs:
1 2 4 8 16
On the other hand, change this:
static unsigned value = 0;
to this:
static unsigned value; value = 0;
And the resulting output is:
1 1 1 1 1
Now I would expect the latter to be the output for both cases because we're initializing value to be 0 at every run of "fun". The way it might work in my mind is if value is initializing like this:
static unsigned value;
So we're initializing it to 0 but not changing it at every run of "fun"
the result for this is also as expected:
1 2 4 8 16
So I don't understand the logic here... Is it something with the static keyword or is it because I'm initializing it twice?
Why should I initialize static class variables in C++? - Stack Overflow
Initialize static variables in C++ class? - Stack Overflow
initializing static variable - C++ Forum
The ins and outs of local static variable initialization
What is a static variable in C?
Why use static variables in C?
What happens if a static variable is not initialized?
Videos
At class scope,
int MyClass::classVar = 0; // Why I have to init it here?
is a definition and
static int classVar;
is a declaration, ie. a promise the variable will be defined somewhere: you must define exactly once the variables you declare.
The rationale is that the class declaration will likely be included in multiple source files. Would a part of it be a definition, it would take place multiply: this is erroneous (exceptions are inline [member] functions).
Note that according to value initialization rules, you can get along with
int MyClass::classVar; // Zero-initialized !
as a definition.
Variables declared at namespace scope are definitions too (unless they are extern qualified):
int var;
is a declaration, and a definition: if you put this into a header and include it in multiple translation units, you have an error ("multiply defined symbol", or something along those lines).
[Note that in C++ (and not in C), if the var above is const, it becomes automatically static and there is no violation of the One Definition Rule should it be put into a multiply included header. This goes slightly off topic, but feel free to ask details]
C++ FAQ 10.12 states that:
static data members must be explicitly defined in exactly one compilation unit.
From C++ FAQ http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12
Does that answer your question or were you after a reference to the C++ standard itself?
They can't be initialised inside the class, but they can be initialised outside the class, in a source file:
// inside the class
class Thing {
static string RE_ANY;
static string RE_ANY_RELUCTANT;
};
// in the source file
string Thing::RE_ANY = "([^\\n]*)";
string Thing::RE_ANY_RELUCTANT = "([^\\n]*?)";
Update
I've just noticed the first line of your question - you don't want to make those functions static, you want to make them const. Making them static means that they are no longer associated with an object (so they can't access any non-static members), and making the data static means it will be shared with all objects of this type. This may well not be what you want. Making them const simply means that they can't modify any members, but can still access them.
Some answers including even the accepted answer seem to be a little misleading.
You don't have to
- Always assign a value to static objects when initializing because that's optional.
- Create another
.cppfile for initializing since it can be done in the same header file.
You can even initialize a static object in the same class scope just like a normal variable using the inline keyword.
Initialize with no values in the same file
#include <string>
class A
{
static std::string str;
static int x;
};
std::string A::str;
int A::x;
Initialize with values in the same file
#include <string>
class A
{
static std::string str;
static int x;
};
std::string A::str = "SO!";
int A::x = 900;
Initialize in the same class scope using the inline keyword
#include <string>
class A
{
static inline std::string str = "SO!";
static inline int x = 900;
};
Hi! I'm looking for an up-to-date article/guide/blog post on the initialization of local static variables. Specifically I am interested in learning i.) how the program know that a static variable has been declared, ii.) more how to distinction between an identifier and a variable is present in program code/compiled code (i.e. how again does the program know exactly to what memory address to look for etc.). Thanks!
Fundamentally this is because static members must be defined in exactly one translation unit, in order to not violate the One-Definition Rule. If the language were to allow something like:
struct Gizmo
{
static string name = "Foo";
};
then name would be defined in each translation unit that #includes this header file.
C++ does allow you to define integral static members within the declaration, but you still have to include a definition within a single translation unit, but this is just a shortcut, or syntactic sugar. So, this is allowed:
struct Gizmo
{
static const int count = 42;
};
So long as a) the expression is const integral or enumeration type, b) the expression can be evaluated at compile-time, and c) there is still a definition somewhere that doesn't violate the one definition rule:
file: gizmo.cpp
#include "gizmo.h"
const int Gizmo::count;
In C++ since the beginning of times the presence of an initializer was an exclusive attribute of object definition, i.e. a declaration with an initializer is always a definition (almost always).
As you must know, each external object used in C++ program has to be defined once and only once in only one translation unit. Allowing in-class initializers for static objects would immediately go against this convention: the initializers would go into header files (where class definitions usually reside) and thus generate multiple definitions of the same static object (one for each translation unit that includes the header file). This is, of course, unacceptable. For this reason, the declaration approach for static class members is left perfectly "traditional": you only declare it in the header file (i.e. no initializer allowed), and then you define it in a translation unit of your choice (possibly with an initializer).
One exception from this rule was made for const static class members of integral or enum types, because such entries can for Integral Constant Expressions (ICEs). The main idea of ICEs is that they are evaluated at compile time and thus do no depend on definitions of the objects involved. Which is why this exception was possible for integral or enum types. But for other types it would just contradict the basic declaration/definition principles of C++.