CIsForCookies
CIsForCookies

Reputation: 12817

Is `auto` specifier slower in compilation time?

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

Answers (3)

Ziezi
Ziezi

Reputation: 6467

How does it work:

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...

7.1.6.4 auto specifier

  1. 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.
  2. The auto type-specifier may appear with a function declarator with a trailing-return-type in any context where such a declarator is valid.
  3. 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

Is it faster:

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

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

DevSolar
DevSolar

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

Related Questions