Attention please: you may think this post is a duplicate to this old post. But the said post was more than 12 years ago and none of the answers mentions the C 11 and afterwards.
And what's more, my question is about the comment of the answer which has most votes and my question is about the detailed code snippet below.
As per the comment of this answer, which says that[emphasise mine]:
With C 11 you can do this in stack too; B obj{}; will make the object value-initialized (to 0s) as opposed to B obj; which will be default-initialized (garbage).
But it seems that there is no difference between them for this code snippet. Tips: Pay attention to the outputs of the said code snippet.
new Line()
is default-initialized but it's not garbage indeed.
Here is the aforementioned code snippet:
#include <utility>
#include <iostream>
#include <string>
template<typename T>
struct Point {
T x;
T y;
};
struct Line{
Point<double> head;
Point<double> tail;
double *demo;
int color;
//std::string comment;
};
template<typename T>
std::ostream& operator<<(std::ostream& os, const Point<T>& point)
{
os << "(" << point.x <<"," << point.y <<")";
return os;
}
std::ostream& operator<<(std::ostream& os, const Line& line)
{
os << "head: " << line.head << std::endl;
os << "head: " << line.tail << std::endl;
os << "demo=" << static_cast<void*>(line.demo) << std::endl;
os << "color=" << line.color << std::endl;
//os << "string=" << line.comment << std::endl;
return os;
}
int main()
{
auto ptr2lineWithBracket = new Line();
std::cout << *ptr2lineWithBracket;
std::cout << "==================" << std::endl;
auto ptr2lineWithout = new Line;
std::cout << *ptr2lineWithout;
}
Here is the output:
head: (0,0)
head: (0,0)
demo=0
color=0
==================
head: (0,0)
head: (0,0)
demo=0
color=0
CodePudding user response:
Question about some specific differences between new T() and new T
new T()
is value initialisation. For aggregate classes such as Line
and Point<T>
this means that all sub objects are value initialised. For primitive objects such as double*
and int
this means zero initialisation.
new T
is default initialisation. For aggregate classes such as Line
and Point<T>
this means that all sub objects are default initialised. For primitive objects such as double*
and int
this means no initialisation. If an object isn't initialised1, then it has an indeterminate value. This means that their value is indeterminate. If a program reads an indeterminate value (of a type other than narrow character type), then the behaviour of the program is undefined. This is to be avoided. Don't do this.
The example program reads indeterminate values, and its behaviour is undefined.
in C 11 and afterwards
There hasn't been a change regarding these since C 03 where value initialisation was added to the language.
Not related to the example directly, but a new syntax was added for value initialisation in C 11:new T {}
(in addition to analogous syntaxes using curly braces for temporary and variable initialisation).
1 Note that objects with static storage duration are zero initialised before any other initialisation regardless of the syntax you use.