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.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I want to make all the variables which I create in my program to have initialization to zero without doing it explicitly.
For example suppose if I create a variable like below:
int i;
We know that it must contain any garbage value and to make it have value 0 by default we need to declare it like
int i=0;
but I want my all variables in the program to contain garbage value as 0 not any other value.
In my code I want my every variables (which include class variables, global variables, local variables) to automatically initialize to 0 without doing it explicitly.
So what logic I tried is that in C, I have written the "Hello World" program without using main() function. So what I have done in that time is to override the _start function which is the first function called by compiler to set up everything and then call to main(). So I think there must be a function which compiler calls during the creation of a variables and I thought we can set the value 0 to the all variables there. Please help me with this problem. If there exist some other logic to solve this problem you can share with me I am open to all solutions but please don't say to explicitly declare them with the value 0.
As a person who spends much of his working life looking at other people's broken code, I really have to say this, although I doubt it will be popular...
If it matters what the initial value of a variable is, then you should initialize it explicitly.
That's true even if you initialize it to what is, in fact, the default value. When I look at a statement like this:
int i = 0;
I immediately know (or think I know) that the programmer really thought about the value, and set it. If I read this:
int i;
then I assume that the programmer does not care about the value -- presumably because it will be assigned a value later.
So far as automatic variables are concerned, it would be easy enough for the compiler to generate code that zero'd the relevant part of the stack frame on entry to a function. I suspect it would be hard to do in application code; but why would you want to? Not only would it make the program behave in a way that appears to violate the language specifications, it would encourage slopping, unreadable programming practices.
Just initialize your variables, and have done with it. Or, if you don't want to initialize it because you know that the compiler will initialize it in the way you want, insert a comment to that effect. You'll thank yourself when you have to fix a bug five years later.
Default initialization and some words regarding the complexity of initialization in C++
To limit the scope of this discussion, let T be any kind of type (fundamental such as int, class types, aggregate as well as non-aggregate), and the t be a variable of automatic storage duration:
int main() {
T t; // default initialization
}
The declaration of t means t will be initialized by means of default initialization. Default initialization acts differently for different kind of types:
For fundamental types such as int, bool, float and so on, the effect is that t is left in an uninitialized state, and reading from it before explicitly initializing it (later) is undefined behavior
For class types, overload resolution resolve to a default constructor (which may be implicitly or implicitly generated), which will initialize the object but where its data member object could end up in an uninitialized state, depending on the definition of the default constructor selected
For array types, every element of the array is default-initialize, following the rules above
C++ initialization is complex, and there are many special rules and gotchas that can end up with uninitialized variable or data members of variables whence read results in UB.
Hence a long-standing recommendation is to always explicitly initialized you variables (with automatic storage duration), and not rely on the fact that default initialization may or may not result in a fully initialized variable. A common approach is (attempting) to use value initialization, by means of initialization of variable with empty braces:
int main() {
int i{}; // value-initialization -> zero-initialization
SomeAggregateClass ac{}; // aggregate initialization
}
However even this approach can fail for class types if one is not careful whether the class is an aggregate or not:
struct A {
A() = default; // not user-provided.
int a;
};
struct B {
B(); // user-provided.
int b;
};
// Out of line definition: a user-provided
// explicitly-defaulted constructor.
B::B() = default;
In this example (in C++11 through C++17), A is an aggregate, whereas B is not. This, in turn, means that initialization of B by means of an empty direct-list-init will result in its data member b being left in an uninitialized state. For A, however, the same initialization syntax will result in (via aggregate initialization of the A object and subsequent value initalization of its data member a) zero-initialization of its data member a:
A a{};
// Empty brace direct-list-init:
// -> A has no user-provided constructor
// -> aggregate initialization
// -> data member 'a' is value-initialized
// -> data member 'a' is zero-initialized
B b{};
// Empty brace direct-list-init:
// -> B has a user-provided constructor
// -> value-initialization
// -> default-initialization
// -> the explicitly-defaulted constructor will
// not initialize the data member 'b'
// -> data member 'b' is left in an unititialized state
This may come as a surprise, and with the obvious risk of reading the uninitialized data member b with the result of undefined behaviour:
A a{};
B b{}; // may appear as a sound and complete initialization of 'b'.
a.a = b.b; // reading uninitialized 'b.b': undefined behaviour.
This question already has answers here:
Direct Initialization vs Copy Initialization for Primitives
(4 answers)
Closed 5 years ago.
Recently I saw a quite old code in C++, where int var(12) was used instead of int var=12. Why does it work? And should I avoid writing this style of declaration?
There are three ways of initializing variables are valid in C++.
type identifier = initial_value;
For example, to declare a variable of type int called x and initialize it to a value of zero from the same moment it is declared, we can write:
int a=5; // initial value: 5
type identifier (initial_value);
A second method, known as constructor initialization (introduced by the C++ language), encloses the initial value between parentheses (()):
int b(3); // initial value: 3
type identifier {initial_value};
Finally, a third method, known as uniform initialization, similar to the above, but using curly braces ({}) instead of parentheses (this was introduced by the revision of the C++ standard, in 2011):
int c{2}; // initial value: 2
You should check Documentation section Initialization of variables
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.
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.
I have recently fixed a bug in an application of mine: the problem was that an object that resides on the stack had a field left uninitialized.
The object had a class declaration of this type:
struct A{
int somefield, someotherfield;
A(): someotherfield(0) {}
}
and when declaring a local variable (like A var; in a function), somefield was left uninitialized, and so a read of it would return a randomish value.
I was certain that fields of a class, which don't appear in the constructor initialization list, would always get initialized by a synthesized trivial constructor (in the case of an int, a zero value). Evidently I am wrong.
So what are the general rules about implicit field initialization?
classes and structs are initialized by contructor
Basic types int double char short ... are not initialized and contain random numbers
Pointers are not initialized and point to random positions
arrays of classes or structs cause each element to be initialized by its constructor
arrays of basic types or pointers are random.