Reputation: 55
I am researching an interesting behavior for two code segments, that give me unexpected behavior.
#include <iostream>
using namespace std;
int main()
{
long long n;
long long m;
// cin >> n;
cout << m;
return 0;
}
When I run this (for example in https://www.onlinegdb.com/online_c++_compiler), the value printed in the console (the value inside the variable m
) is 0. This is expected and corresponds to the fact that the long long
type has a default initialization to 0 (zero initialization).
#include <iostream>
using namespace std;
int main()
{
long long n;
long long m;
cin >> n;
cout << m;
return 0;
}
By uncommenting the line with cin and adding any value, I do not get 0, but rather a different value depending on the number I input for n
. Other characteristics of this behavior are:
n
, we get different values in m
.n
, we get the same value in m
.n
or m
static results in the expected behavior, which is m
carrying the value 0.m
, n
are int
sThe unexpected behavior is thus that m
does not have a default initialization to 0.
cin >> n
, creates a new thread for execution.m
is not initialized in the original stack, the value it carries is indeterminate in the new stack. It depends on the state of the current stack. But the state of the stack is dependent on the state of the original copied stack, which, in turn, is dependent on the value of the input n
.My explanation is congruent with characteristic 3. Nevertheless, I do not know how to check for this using a single thread. Moreover, the reason might be something more than stack-related such that even with one and only one thread, the behavior persists. What do you think?
Upvotes: 0
Views: 180
Reputation: 122830
C++ initialization is super complicated. However, this case is rather simple (confusing terminology aside ;). You are right that both m
and n
are default initialized. Though, immediately after that your interpretation is rather off. It starts with
This is expected and corresponds to the fact that the long long type has a default initialization to 0 (zero initialization).
Default initialization for long long int
is not zero initialization. Actually it is no initialization at all. From cppreference:
Default initialization is performed in three situations:
- when a variable with automatic, static, or thread-local storage duration is declared with no initializer;
[...]
and
The effects of default initialization are:
- if T is a non-POD (until C++11) class type, [...
long long
is not a class type ...]- if T is an array type, [...
long long
is not an array type ...]- otherwise, no initialization is performed: the objects with automatic storage duration (and their subobjects) contain indeterminate values.
Reading an indeterminate value is undefined behavior. Adding or removing seemingly unrelated lines of code changing the output is typical effect of undefined behavior. The output of your code could be anything. It is undefined.
Upvotes: 4