Drise
Drise

Reputation: 4388

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

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

auto packet = DataPacket(); 

and

DataPacket packet;

?

Upvotes: 5

Views: 639

Answers (5)

Jonathan Wakely
Jonathan Wakely

Reputation: 171383

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.

Upvotes: 14

Daniel Fleischman
Daniel Fleischman

Reputation: 657

In this case I would suggest using the second syntax (without the "auto" keyword), since it is less verbose.

This is one example where auto makes sense:

map<int, pair<string, double>> M;
.... // Fill up M
// Without "auto":
map<int, pair<string, double> >::iterator it = M.find(5);
// With "auto":
auto autoit = M.find(5);
// Yet another example:
// Without auto:
for (pair<const int, pair<string, double>>& x: M) {
   // Do stuff
}
// With auto:
for (auto& x : M) {
   // Do stuff
}

Upvotes: 0

N_A
N_A

Reputation: 19897

From the compiler's point of view there is no difference, other than that you can specify a parent type for the variable if you declare it explicitly. Stylistically it affects readability (although whether it's a positive or negative effect depends on the person).

Edit: As was pointed out, the first one does a copy construction while the second uses the default constructor. Pedantic explanation of the differences found here.

Upvotes: 4

Taedrin
Taedrin

Reputation: 535

The auto keyword can be useful when you do not know the type of some expression. You are essentially asking the compiler to determine the variable's type at compile time. There is absolutely no difference between using the auto keyword and using the type explicitly as far as the compiler is concerned.

You can also use the auto keyword to determine the return type of a function, whose return type is not known until compile time (happens with some templated functions). See this Wikipedia article: Alternative function syntax.

Note that the auto keyword does NOT give you RTTI. The auto-type is determined statically at compile time.

Back in the old C days, the auto keyword declared that the variable would have "automatic" storage on the stack, as opposed to being stored in the static data area.

Upvotes: 1

Ben Voigt
Ben Voigt

Reputation: 283733

The first one is copy-initialization, and will fail if no copy or move constructor is accessible.

Upvotes: 10

Related Questions