Default initialization in main() function [duplicate] - c++

This question already has answers here:
Uninitialized variable behaviour in C++
(4 answers)
Closed 6 years ago.
#include <iostream>
using namespace std;
int main() {
int var; // default initialization var = 0 Why?
cout << var << endl;
return 0;
}
If i understand default initiaization right, int variable must be indeterminate value.
The effects of default initialization are:
1) if T is a non-POD (until C++11) class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object;
2) if T is an array type, every element of the array is default-initialized;
3) otherwise, nothing is done: the objects with automatic storage duration (and their subobjects) are initialized to indeterminate values.
So, why int var equal 0 in that case?

Your understanding is correct. var here contains garbage value here, it just happened to be 0.
Garbage value doesn't have to be some seemingly random value, usually it's the value that happened to be in that memory. Run your program again, or change a different compiler, probably you'll see a different result.

Related

Pointers Default initialized Value is not NULL?

How do we know pointers are not initialized to NULL by default?
There is a similar questions directed at Why aren't pointers initialized with NULL by default?
Just for checking, here is a very simple code just to see if a pointer is set to NULL by default.
#include <iostream>
using namespace std;
int main()
{
int* x;
if(!x)
cout << "nullptr" << endl;
return 0;
}
and at the output, I received nullptr message. I appreciate if someone can clarify this.
How do we know pointers are not initialized to NULL by default?
Because we know that the standard says that default initialised pointer has an indeterminate value if it has automatic or dynamic storage. Quote from the standard (draft):
[dcl.init] If no initializer is specified for an object, the object is default-initialized. When storage for an object
with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if
no initialization is performed for the object, that object retains an indeterminate value until that value
is replaced. ...
And further:
[dcl.init] To default-initialize an object of type T means:
— If T is a (possibly cv-qualified) class type [pointer isn't a class, so we don't care]
— If T is an array type [pointer isn't an array, so we don't care]
— Otherwise, no initialization is performed.
I have declared a char (and also int) pointer without initializing it , and I got null pointers.
Reading an indeterminate value has undefined behaviour. Quote from the standard (draft):
[dcl.init] ... If an indeterminate value is produced by an evaluation, the behavior is undefined except in the
following cases: [cases which don't apply here]
The question you linked to handles variables with local storage duration exclusively, so I assume you refer to these as well.
Such variables are not initialised if you don't do so yourself, so they get the value of whatever was written in their memory location before (standard wording: their value is 'indeterminate') – nothing speaks against, though, that this memory already is zero – by pure accident!
You can try the following:
void test()
{
int* p; // uninitialized
std::cout << p << std::endl; // undefined behaviour!!!
// (that's what you most likely did already...)
// now something new: change the memory...
p = reinterpret_cast<int*>(static_cast<uintptr_t(0xaddadaad));
}
int main()
{
test();
// again something new: call it a SECOND time:
test();
}
As this is undefined behaviour there are no guarantees at all that you will get any meaningful output – chances are, though that the memory of first function call is reused in second one and you might get output ressembling to the following:
00000000
addadaad
So even if there just happened to be all zero memory at programme start, it might differ from that at some later point while your programme is running...

Range of indexes not default initialized in arrays in C++

The following is the code I am trying to run
#include<bits/stdc++.h>
using namespace std;
int main()
{
bool x[101010];
for(int i=0;i<101010;i++)
{
if(x[i])
cout<<i<<" ";
}
return 0;
}
As far as I know, the default value of boolean type variables is false. However, for the above code from index 94758-101008 value of i is being printed which means they are default initialized as true.
Can anyone please help me in figuring out where am I going wrong?
Your problem can be reduced to this:
bool x;
std::cout << x;
A boolean is a fundamental type. Default initializing automatic variables of a fundamental type leaves them with indeterminate values. Not false, but indeterminate. Using those values leads to undefined behavior. This is what you are seeing.
The reason you see random values is that "behind the curtain" a boolean is an integer type that the compiler enforces only two values on. But if you don't initialize it explicity, you'll get whatever random junk is that memory.
The solution is to explicitly value-initialize your variables. For an array, it would look like this:
bool x[101010]{};
That will recursively value initialize each element of the array, and to value initialize a bool is indeed to set it to false.
the default value of boolean type variables is false.
It's not true here. For default initialization,
if T is a non-POD (until C++11) class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object;
if T is an array type, every element of the array is default-initialized;
otherwise, nothing is done: the objects with automatic storage duration (and their subobjects) are initialized to indeterminate values.
x is declared as local object with automatic storage duration, and it's an array with non-class type; then the value of all the elements of x will be indeterminate values.

Does C++ standard guarantee that,using {}/() for initialization will give "0" by default? [duplicate]

This question already has answers here:
What do the following phrases mean in C++: zero-, default- and value-initialization?
(2 answers)
Closed 6 years ago.
Question1:
struct S
{
size_t size;
int j;
int k;
int l;
};
S s={sizeof(S)};
Doest C++ standard say,the above {} will initialize "j,k,l" to 0?
Seems it will do, is it part of cpp standard?
Question2:
int main()
{
int* pi=new int[5];
for(int i=0;i<5;++i)
cout<<pi[i]<<',';
return 0;
}
Here the elements in pointer to array(pi) are not initialized, my running result may look like
6785200,6782912,0,0,0,
But if I change it to
int main()
{
int* pi=new int[5]();//use ()
for(int i=0;i<5;++i)
cout<<pi[i]<<',';
return 0;
}
Then, all pi elements are "0". Seems "()" will give elements a "0" value. Is this part of cpp standard?
I also tried to give another value using "()" like this:
int* pi=new int[5](7);
But it fails compilation. How could I give initialization values to an pointer to array with all elements having same value?
Question 1
Yes, it is guarantied by aggregate initialization
in particular:
If the number of initializer clauses is less than the number of members [and bases (since C++17)] or initializer list is completely empty, the remaining members [and bases (since C++17)] are initialized [by their default initializers, if provided in the class definition, and otherwise (since C++14)] by empty lists, which performs value-initialization. If a member of a reference type is one of these remaining members, the program is ill-formed (references cannot be value-initialized).
.
Question 2
Use std::vector:
std::vector<int> pi(5, 7);
There is a perfect answer to question 1 already, I will answer question 2.
Yes, your observation is correct. Adding () after the new turns default initialization of the elements into value initialization. The first form does nothing with created objects (so you observe random numbers), but the value initialization will initialize members - and in this case, will set elements to 0. Unfortunately, there is no way to perform a specific initialization for dynamic int arrays - you can either leave them uninititalized or value-initialize them (to 0).
Using std::vector solves this problem.

On which occasions will c++ initialize variables with zero? [duplicate]

This question already has answers here:
Default variable value
(10 answers)
Closed 9 years ago.
Every variable should be properly defined and initialized(assign a value to it) before being used. However under some circumstances, c++ will set variables with a default value of zero. Like the case below.
class A{
...
static int val;
...};
//int val = 10; //This is the usual definition.
int val;//Definition without assigning a value.
...
A a; //a class A object
std::cout<<a.val;
The result would be zero. Obviously, the compiler did something to initialize variable a.val to zero. I am curious about when will they do this generally?
http://en.cppreference.com/w/cpp/language/zero_initialization
Zero initialization is performed in the following situations:
For every named variable with static or thread-local storage duration, before any other initialization.
As part of value-initialization (i.e. with an empty pair of parentheses or braces) sequence for non-class types and for members of value-initialized class types that have no constructors.
When a character array is initialized with a string literal that is too short, the remainder of the array is zero-initialized.

C++ default initialization of built-in types [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Do all "real" C++ compilers don't have default initialization with zeros of built-in types? I'm asking 'cos I've found on-line compilers that is claimed to be gcc, and it does zero initialization of built-in types
int h=6548;
for (int i; i < 10; ++i) {
cout<<i<<"\n";
}
for this code its output is
0
1
2
3
4
5
6
7
8
9
What initialization. In your example, accessing i is
undefined behavior, since it wasn't initialized. Some compilers
do initialize it, at least in debug mode, but generally with
something like 0xDEADBEEF or 0xCCCCCCCC, so that you can
easily recognize in a debugger that you're accessing
uninitialized memory (and so that the program is likely to crash
if you use it as a pointer), but this is not required.
The only time built-in types are implicitly initialized is when
they have static storage duration: variables defined at
namespace scope (include static class members), or local
variables which have been declared static.
You don't show the context of your code, but if it is directly
in main, or in the first function called from main, int i
will be the first use of this actual memory. And the OS
probably will have set it to 0, for security reasons. You might
want to try something like:
void scribble()
{
int x = 0x12345678;
}
void testit()
{
for ( int i; i < 10; ++ i ) {
std::cout << i << '\n';
}
}
int
main()
{
scribble();
testit();
return 0;
}
The call to std::operator<<( std::ostream&, char const* ) is
might have left something different from 0 in this
particular memory cell. (Or the compiler has optimized it out.
Try this with all optimization turned off.) Neither g++ nor
VC++ initialize the i in testit.
Whether or not the values are initialized is undefined behaviour and implementation dependant. You must not rely on that.
1. C++11, 8.5/11
If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. —end note ]
If you use int i; this results in an uninitialized integer which has "indeterminate value"! You can't predict what will happen if you access it's value.
2. C++11, 8.5/10
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
If you use int i = int(); you have a value-initialized i. Now, what is value-initialized?
3. C++11, 8.5/7
To value-initialize an object of type T means:
[...] (some options where T may be class or array type)
otherwise, the object is zero-initialized.
Ok now we know that int i = int(); means having i=0.
Be aware of the following:
Note: Since () is not permitted by the syntax for initializer,
    X a();
is not the declaration of a value-initialized object of class X, but the declaration of a function taking no argument and returning an X.
Emphasis on standard quotes are mine.
Both the C and C++ standards are VERY clear that there is only one kind of memory that is initialize, and that is the memory for static storage.
Variable with static storage duration are guaranteed to be zero (that aren't initialized or have a constructor). Everything else is "uninitialized", which means "you don't know what it will be" - and one of the options is of course that it is zero.
All other variables are almost guaranteed to not be zero, at least under some circumstances - and it may well be that you can't find those circumstances with a simple test program.
For example, malloc (or new) memory is often zero for "virgin" memory, but fill it with something, then free it and use it again, and it's no longer zero.
Variables on the stack almost inevitably will have different values depending on what the previous call was (and thus, what stuff got put on the stack in the previous function that the code visited).
NO one compiler initialize with zero. I can say that somehow you were lucky.
Try this in online compiler you gave.
for(int i;i < 10; ++i)
{
int a;
cout << a << endl;
a = 1;
}
And you will see that first time a is equal 0 and next 9 times it's equal 1.
It may depend on compilers to compilers, but it is better to make initialization a habit because you may not know which old compiler you may end up with and you may get screwed up by using the uninitialized garbage values....
Another compiler is http://codepad.org/ which also initializes on its part..