int j = g(); // Good -- declaration has initialization.
vector<int> v;
v.push_back(1); // Prefer initializing using brace initialization.
v.push_back(2);
vector<int> v = {1, 2}; // Good -- v starts initialized.
Note that gcc implements for (int i = 0; i < 10; ++i) correctly (the scope of i is only the scope of the for loop), so you can
then reuse i in another for loop in the same scope. It also correctly scopes declarations in if and while statements, e.g.
while (const char* p = strchr(str, '/')) str = p + 1;
There is one caveat: if the variable is an object, its constructor is invoked every time it enters scope and is created, and its
destructor is invoked every time it goes out of scope.
// Inefficient implementation:
for (int i = 0; i < 1000000; ++i) {
Foo f; // My ctor and dtor get called 1000000 times each.
f.DoSomething(i);
}
It may be more efficient to declare such a variable used in a loop outside that loop:
Foo f; // My ctor and dtor get called once each.
for (int i = 0; i < 1000000; ++i) {
f.DoSomething(i);
}
Static or global variables of class type are forbidden: they cause hard-to-find bugs due to indeterminate order of construction and destruction. However, such variables are allowed if they are constexpr: they have no dynamic initialization or destruction.
Objects with static storage duration, including global variables, static variables, static class member variables, and
function static variables, must be Plain Old Data (POD): only ints, chars, floats, or pointers, or arrays/structs of POD.
The order in which class constructors and initializers for static variables are called is only partially specified in C++ and
can even change from build to build, which can cause bugs that are difficult to find. Therefore in addition to banning
globals of class type, we do not allow static POD variables to be initialized with the result of a function, unless that
function (such as getenv() , or getpid() ) does not itself depend on any other globals.
Likewise, global and static variables are destroyed when the program terminates, regardless of whether the termination
is by returning from main() or by calling exit() . The order in which destructors are called is defined to be the reverse of
the order in which the constructors were called. Since constructor order is indeterminate, so is destructor order. For
example, at program-end time a static variable might have been destroyed, but code still running — perhaps in another
thread — tries to access it and fails. Or the destructor for a static string variable might be run prior to the destructor for
Static and Global Variables