views:

159

answers:

5

Hi all,

This is a (hopefully) really simple question - I have been told recently that using C++ style initialisation is better than traditional (and more common) assignment.

So this code:

std::SomeSTLContainer::const_iterator it = container.begin();
std::SomeSTLContainer::const_iterator itEnd = container.end();

would be 'slower' or less efficient than:

std::SomeSTLContainer::const_iterator it ( container.begin() );
std::SomeSTLContainer::const_iterator itEnd ( container.end() );

I understand the reason for this - the first example causes default construction and initialisation then subsequent assignment rather than specific construction and direct assignment in the second example. However, on modern processors / compilers, does it really make a difference?

+8  A: 

I have been told recently that using C++ style initialisation is better than traditional (and more common) assignment.

This is simply wrong.

I understand the reason for this - the first example causes default construction and initialisation then subsequent assignment rather than specific construction and direct assignment in the second example. However, on modern processors / compilers, does it really make a difference?

No, it doesn't make a difference. The C++ standard explicitly allows the assignment in that case to be omitted so that the same code will be produced. In practice, all modern C++ compilers do this.

Additionally, Charles is right: this would never call the assignment operator but rather the copy constructor. But as I've said, even this doesn't happen.

Konrad Rudolph
Does your "No, it doesn't" refer to my entire second paragraph or just the "does it really make a difference?" question? :) If the former, can you set me straight.
Konrad
it refers to the difference. Wait, I edit it.
Konrad Rudolph
One reason to prefer the second form is that it is arguably more explicit about what is going to happen. It helps someone who is reading the code understand that the copy constructor will be used.
Andy Balaam
+3  A: 

Your reasoning is not quite correct. Using an '=' in the definition does not cause default construction and assignment. In the 'worst' case, it uses the copy constructor from a temporary generated from the right hand side of the '='.

If the type of the right hand side is (const/volatile aside) of the same type or a derived type of the object being initialized then the two forms of construction are equivalent.

Charles Bailey
A: 

No, typically. This is because iterators are coded to be very thin wrappers, and optimizers are quite aggressive when it comes to thin wrappers. E.g. the normal iterator method is just a simple pointer operation, and the function body is available from the header. This makes it trivially inlinable. In this case, an iterator copy is behind the scenes probably just a pointer copy, so the same holds.

MSalters
Nice point about iterators but not quite applicable since the same code will be produced in both cases even for more heavyweight classes.
Konrad Rudolph
A: 

This really depends on the case and the general rule of thumb should be applied: measure.

If there are a lots of instantiations of those iterators (maybe in nested and sort loops, those shorter constructors can easily make a difference). Altough as you suggested, many compilers already can optimize those on their own.

To be really sure if your compiler does this there is just one way: measure

Kosi2801
A: 

A a = A( arg1, arg2, ... );

This assignment can, as Rudolf stated, be replaced by a simple construction: it's a construction. And indeed, it would be compiled into the equivalent of the more succinct

A a( arg1, arg2, ...);

It's mostly a style issue, but I prefer not mixing the 'assigment-style' construction with 'initializer-style' construction. This way I induce consistency throughout my code. This boils down to: always use initializer style construction :).

xtofl