Reputation: 12817
Since C++11 we can use auto a = 1+2
instead of int a = 1+2
and the compiler deduces the type of a
by itself. How does it work? Is it slower during compile time (more operations) than declaring the type myself?
Upvotes: 19
Views: 7775
Reputation: 6467
From the ISO/IEC:
...The auto specifier is a placeholder for a type to be deduced (7.1.6.4). The other simple-type-specifiers specify either a previously-declared user-defined type or one of the fundamental types...
- The auto type-specifier signifies that the type of a variable being declared shall be deduced from its initializer or that a function declarator shall include a trailing-return-type.
- The auto type-specifier may appear with a function declarator with a trailing-return-type in any context where such a declarator is valid.
- Otherwise, the type of the variable is deduced from its initializer. The name of the variable being declared shall not appear in the initializer expression. This use of auto is allowed when declaring variables in a block, in namespace scope, and in a for-init-statement; auto shall appear as one of the decl-specifiers in the decl-specifier-seq and the decl-specifier-seq shall be followed by one or more initdeclarators, each of which shall have a non-empty initializer...
Example:
auto x = 5; // OK: x has type int
const auto *v = &x, u = 6; // OK: v has type const int*, u has type const int
static auto y = 0.0; // OK: y has type double
auto int r; // error: auto is not a storage-class-specifier
The simple answer is Yes, by using it a lot of type conversions could be omitted, however, if not used properly it could become great source of errors.
In one of the interviews from Bjarne Stroustrup, he said that auto
keyword has resulted in win-win situation for coders and compiler implementers.
Upvotes: 7
Reputation: 1
auto
is asking the C++11 compiler to make some limited kind of type inference (look into Ocaml if you want some more sexy type inference language). But the overhead is compile-time only.
If you replace auto a=1+2;
with int a=1+2;
(both have the same meaning, see answer by simplicis) and if you ask your compiler to optimize (and probably even without asking for optimizations) you'll probably get the same machine code. See also this.
If using GCC try to compile a small C++11 foo.cc
file with g++ -Wall -fverbose-asm -O -S foo.cc
and look (with an editor) into the generated foo.s
assembler file. You'll see no difference in the generated code (but the assembler file might perhaps change slightly, e.g. because of metadata like debug information etc.)
If you are concerned about slower compile-time I guess that using auto
is not a decisive factor (probably, overloading could be more costly in compilation time). C++11 is nearly designed to practically require a lot of optimizations (in particular sophisticated inlining and constant folding and dead code elimination), and its "parsing" (notably header inclusion and template expansion) is costly.
Precompiling headers and parallel builds with make -j
(and perhaps ccache
or distcc
) might help in improving the overall compilation time, much more than avoiding auto
.
And if you wanted to systematically avoid auto
(in particular in range-for loops like std::map<std::string,int> dict; for (auto it: dict) {
...}
) you'll end up typing much more source code (whose parsing and checking takes significant time) with more risks of error. As explained here, you might guess slightly wrongly the type, and expliciting it (slightly wrongly) might slow down the execution of your code because of additional conversions.
If using GCC you might pass the -ftime-report
to g++
and get time measurements about various GCC passes and phases.
Upvotes: 19
Reputation: 70303
The compiler knows the type an expression (like 1 + 2
) evaluates to. That's just the way the language works -- both operands are of type int
so the result is int
as well. With auto a
, you are just telling the compiler to "use the type of the initializing expression".
The compiler does not have to do any additional work or deducing here. The auto
keyword is merely relieving you from figuring out the expression and writing the correct type. (Which you might get wrong, with probably unintended side-effects -- see this question (and the top answer) for an example how auto
can avoid unintended run-time conversions and copying.
The auto
keyword really comes into its own with iterators:
std::vector< std::string >::const_iterator it = foo.cbegin();
versus
auto it = foo.cbegin();
Upvotes: 9