Reputation: 32484
This question is the opposite of an existing question "Can the use of C++11's 'auto' improve performance?"
One of the answers to that question indicated that usage of auto
can have not only positive but also negative effects.
I believe we need a separate question, with answers focusing on that side of auto
.
Upvotes: 4
Views: 615
Reputation: 1212
Blind search-and-replace of all type declarations by auto can be a head-ache, whenever braced initialization is used:
class Point
{
public:
Point (int x1, int y1) { x = x1; y = y1; }
private:
int x, y;
};
int main()
{
Point p{5, 6};
auto q{5, 6}; // Error. Uniform initialization is not REALLY uniform
}
The first declaration of variable p is correctly deduced as a call to the constructor accepting two integers. But the auto variable q searches for a constructor requiring std::initializer_list<int
> and hence fails to compile.
Upvotes: 0
Reputation: 24259
Your question title specifies 'performance'.
auto
is a compile time construct that allows itself to be substituted with a deduced type. Its use doesn't result in different machine instructions, than if you have hand-written the typename it deduced.
The problem is that, in managing performance, type specification and casting is often crucial, and auto
can hide that leading programmers to say something different than they intended:
std::vector<std::array<BigStruct, 10000>>& f();
auto va = f(); // copy
for (auto v: va) { // copies
// ...
}
if the programmer had written:
std::vector<std::array<BigStruct, 10000>> va = f();
or
for (std::array<BigStruct, 10000> v : va)
they would have recognized they were specifying by-value. But std::array<BigStruct, 10000>
is what auto
deduces here and in these cases that translates to by-value.
People drop their guard and forget that auto
deduces the type, it doesn't include the ref qualification.
auto& va = f(); // reference
for (auto& v : va) { // references
There was a performance affect here, but it wasn't caused by auto
it was a side-effect of (accidentally) explicitly specifying a copy.
auto
doesn't mean the same as this
it means an instance of this
.
auto va = f(); // an instance-of what f returns, thus a copy.
auto& va = f(); // a reference to an instance-of, thus by reference.
Upvotes: 2
Reputation: 32484
With auto
there is no conversion at the variable declaration+initialization line. But if such conversion must happen anyway, it better happen once during initialization than multiple times later.
struct X {
...
};
struct Y {
operator X() const;
...
};
Y foo(); // maybe, originally its return type was X but later was changed to Y
void bar(const X& );
const auto x = foo(); // <-- conversion not happening here
//
for ( int i = 0; i < 100; ++i ) //
bar(x); // <-- silently rages here
Such a deferred conversion may break the code when auto
is combined with lazy evaluation (real world example 1, example 2):
class Matrix { ... };
class MatrixExpression {
...
operator Matrix() const;
};
MatrixExpression operator+(const Matrix& a, const Matrix& b);
std::ostream& operator(std::ostream& out, const Matrix& m);
Matrix a = ...;
Matrix b = ...;
auto c = a + b; // evaluation of the matrix addition doesn't happen here
a[0][0] += 1;
std::cout << c; // matrix addition is evaluated here, using the new state of 'a'
Upvotes: 5