Reputation: 99
I've recently read a programming book. It says that if we don't give a value when initializing the variable like in the example given below:
int i;
int i {0};
... then it might result in runtime errors sometimes. However, I'm not sure if this is correct. Will an uninitialized variable be set as a random integer? Why might this cause a runtime error?
I haven't experienced this kind of runtime error yet. Is it important to give the init value to a variable?
Upvotes: 2
Views: 1000
Reputation: 335
You shouldn't be using a variable before a value is assigned to it. Most compilers will inform you of that, which generally means a program logic mistake. Sticking a value on a declaration masks those errors, and leads to bug.
Personally, I don't like the idea.
Upvotes: 0
Reputation: 99
Thanks for the response above. I wrote some code and run tests in different optimize level in my computer(linux 6.2.0-24-generic). The result was given below:
❯ g++ varinit.cpp -o varinito3 -O3
g++ varinit.cpp -o varinito2 -O2
g++ varinit.cpp -o varinito1 -O1
g++ varinit.cpp -o varinito0 -O0
❯ ./varinito3
0
❯ ./varinito2
0
❯ ./varinito1
0
❯ ./varinito0
32766
❯ icpx varinit.cpp
❯ ./a.out
-1884400440
I notice that in optimized build (G++) int variable will be default initialized as zero, but in no optimize compile, the default value is random constant (will not change by time when you run it). In addition, in intel cpp compiler(icpx) the value is random but changes each time you compile it.
Upvotes: 0
Reputation: 123114
Yes the book was right. It is a common recommendation to always initialize variables as soon as you declare them. The reason is that reading from an uninitialized variable invokes undefined behavior.
This code
int evil;
std::cout << evil;
Might look ok in a debug build. In a debug build the compiler does more than it needs. It might do the initialization for you. Though, in a debug build the compiler also does less then in a release build: It does not apply optimizations. It does not analyze your code and transform it for better performance, as it would in a release build. Thats why the above code can appear fine in a debug build while in a release build bad things can happen.
Suppose you know that you are not allowed to read from an uninitialized variable and you write:
int ok;
ok = 42;
std::cout << ok;
Then all is fine. However, usually code doesnt look that simple. It rather looks like this:
int notok;
if (some_condition) {
notok = 42;
} else {
std::cout << "hello world";
}
std::cout << notok;
It is easy to accidentally use a variable that has not been initialized. Hence the recommendation to always initialize them:
int good = 42;
Upvotes: 0
Reputation: 409422
In C++, non-static variables in function scope (inside of functions, also known as local variables), or class member variables without any other initialization, doesn't get initialized by default. They will have an indeterminate value. Using an indeterminate value in any way leads to undefined behavior.
Unless you're using uninitialized pointers, it's unlikely that you will get a crash (though some floating-point values could lead to exceptions). Plain integers will just give you unexpected results.
With all this said, you don't have to explicitly initialize all your local variables, if you plan on assigning values to them later (but before you use their values).
Variables defined outside of functions or classes will be value initialized. Which sets their values to zero (or the corresponding value for the type, i.e. pointers become null pointers).
static
local and member variables will also be value initialized.
Upvotes: 3