What is the difference between declaring a variable with auto and using the type name?

advertisements

For example, I have some class DataPacket. What is the difference between:

auto packet = DataPacket();

and

DataPacket packet;

?


To answer the question about auto first, there is no difference in the generated code between:

auto packet = DataPacket();

and

DataPacket packet = DataPacket();

But that's not what you wrote.

In the original question, the first one creates a value-initialized temporary and then copy-initializes packet from it. That requires an accessible, non-explicit copy or move constructor, requires the type can be default-constructed, and ensures packet is initialized (assuming the copy/move constructor isn't buggy.) The second one default-initializes packet which only requires that the type can be default-constructed, but leaves the object uninitialized if it has a trivial default constructor, for example:

struct DataPacket { int i; };
{
  DataPacket packet = DataPacket();
  ++packet.i;  // OK
}
{
  DataPacket packet;
  ++packet.i;  // undefined behaviour
}

As Xeo points out in a comment below, these is less difference between these:

auto packet = DataPacket();

DataPacket packet{};

because the second of those also ensures value-initialization, so in that case the difference is that the former requires an accessible, non-explicit copy or move constructor.

In all the cases that require an accessible copy/move constructor, if the copy (or move) isn't elided then the code generated will be different because of the copy/move. But in practice it will be elided by all modern compilers so the generated code will be identical.