In my code I encountered above kind of scenario. Under what circumstances we need to use above style of object creation? Cant we simply create object X x? What thing we have achieved in X x = X(); type declaration?
-
Today the answer is "Nothing". However, if you're not elliding copies, then theoretically `X x = X()` is allowed to first construct two instances of `X` by default, and then copy/move assign one to the other. – AndyG Oct 03 '16 at 13:18
-
@AndyG Even with elision there is still a (slight) difference: `X x = X()` is ill-formed if `X` is not copyable/movable. – Holt Oct 03 '16 at 13:20
-
1@AndyG It depends on `X`. The difference could be huge. It is default initialization vs. value initialization. See http://stackoverflow.com/questions/1613341/what-do-the-following-phrases-mean-in-c-zero-default-and-value-initializat. – juanchopanza Oct 03 '16 at 13:21
-
Fair enough, thanks for the clarification. – AndyG Oct 03 '16 at 13:22
-
Another possible duplicate: http://stackoverflow.com/q/1051379/27678 – AndyG Oct 03 '16 at 13:26
2 Answers
There is difference. X x = X()
requires the copy constructor to be accessible.
For the following class:
struct Foo
{
Foo() = default;
Foo(Foo const&) = delete;
void* ptr;
};
This will compile:
Foo foo;
and this won't:
Foo foo = Foo();
Furthermore, the first syntax results in default-initialization, so ptr
has undetermined value, while the second would zero-initialize it to nullptr
(if the copy constructor wasn't deleted or inaccessible).
The reasonable default is neither of those - uniform initialization syntax (available since C++11):
Foo foo{};
While less uniform than the name suggests, it leaves your object zero-initialized and is immune to most vexing parse.

- 16,240
- 4
- 46
- 61
-
This is good, but you should mention that uniform initialization syntax is a new feature in C++11; many compilers still default to C++03. – zwol Oct 03 '16 at 15:05
You should almost always write either X x;
or X x{};
When X
is a class type, X x;
declares x
as a variable of type X
and runs the default constructor to initialize it. It could be thought of as shorthand for X x();
, except that, because of the most vexing parse, you can't actually write X x();
.
X x{};
is a new feature in C++11. It's almost, but not quite, the same as X x;
. The important difference is that, with X x{};
, any data members the default constructor doesn't initialize will be automatically initialized to zero. With X x;
, any such members will be left uninitialized. (With a well-written C++ class, there won't be any members left uninitialized, but X x{}
is handy for POD structures, such as the ones you might get from system headers geared for plain C.)
X x = X();
is quite different. It's formally equivalent to
X __temp_0{};
X x(__temp_0);
__temp_0.~X();
except for some details of scope and naming that can't be expressed in the language. It creates an extra temporary variable of type X
and default-initializes it. Then it uses X's copy constructor to initialize x
from the temporary, and finally it destroys the temporary (running its destructor). Whether these two things have the same effects depends on what X's constructors and destructor do, and often also on how good your C++ compiler is at optimizing out "abstraction penalties". And it won't compile at all if X
doesn't have an accessible, implicit copy constructor.

- 135,547
- 38
- 252
- 361
-
This is quite misleading. Depending in `X`, one may leave the objects with uninitialized data members, while the other one doesn't. – juanchopanza Oct 03 '16 at 13:29
-
@juanchopanza *When `X` is a class type*, `X x;` and `X x();` always do exactly the same thing. Whether or not they leave the object with uninitialized data members depends entirely on X's default constructor. – zwol Oct 03 '16 at 13:33
-
No, they don't always do exactly the same thing. Unless you have a non-standard definition of "class type", which maybe you could elaborate on to clarify the answer. – juanchopanza Oct 03 '16 at 13:35
-
@juanchopanza Any type declared with `struct foo` or `class foo` is what I mean. It's possible that I am misremembering something, but I really don't think so. Please give specific references into the C++ standard to back up your contention. – zwol Oct 03 '16 at 13:37
-
Right, so that is not entirely correct. `sturct X { int n;};` for example. For automatic storage `x`, `X x;` leaves `x.n` uninitialized, `X x = X();` leaves it zero-initialized (as does `X x{};`) – juanchopanza Oct 03 '16 at 13:40
-
@juanchopanza You're talking about `X x;` versus `X x = X();`. I am talking about `X x;` versus `X x();`. I should clarify that `X x();` doesn't actually work, because of the most vexing parse, but *if it did work*, it would be exactly the same as `X x;`, *not* `X x = X();` If you define a constructor `X::X(int) {}` you can observe for yourself that `X x((0))` leaves `x.n` uninitialized. – zwol Oct 03 '16 at 14:29
-
You're really making no sense now, sorry. Nobody is comparing a variable declaration to a function declaration here. I refer you back to my first comment. – juanchopanza Oct 03 '16 at 14:32