在编译时,`auto`说明符是否较慢?

CIs*_*ies 11 c++ types compile-time auto c++11

从C++ 11开始,我们可以使用auto a = 1+2而不是int a = 1+2编译器,并且编译器会a自行推断出类型.它是如何工作的?编译时(更多操作)比自己声明类型更慢吗?

Bas*_*tch 15

auto在问C++ 11 的编译器做一些有限的那种类型推断(看看Ocaml程序编写,如果你想要一些更性感的类型推断的语言).但是开销只是编译时间.

如果替换auto a=1+2;int a=1+2;(两者具有相同的含义,请参阅simplicis的回答),如果您要求编译器进行优化(甚至可能不需要优化),您可能会得到相同的机器代码.另请参见.

如果使用GCC尝试编译一个小的C++ 11 foo.cc文件,g++ -Wall -fverbose-asm -O -S foo.cc并在生成的foo.s汇编程序文件中查找(使用编辑器).您将看到生成的代码没有区别(但汇编程序文件可能稍有变化,例如因为调试信息等元数据)

如果你担心编译时间较慢,我猜使用auto不是一个决定性的因素(可能,在编译时,重载可能会更加昂贵).C++ 11几乎被设计为实际上需要大量优化(特别是复杂的内联和常量折叠和死代码消除),并且其"解析"(特别是头部包含和模板扩展)成本很高.

使用make -j(或可能ccachedistcc)预编译头和并行构建可能有助于改善整体编译时间,而不仅仅是避免auto.

如果你想系统地避免auto (特别是在像... 这样的range-for循环中),你最终会输入更多的源代码(其解析和检查需要很长时间),并且存在更多的错误风险.正如这里所解释的那样,您可能会稍微错误地猜测类型,并且明确错误(稍微错误地)可能会因为额外的转换而减慢代码的执行速度.std::map<std::string,int> dict; for (auto it: dict) {}

如果使用GCC你可能会传递-ftime-reportg++并获得各种GCC通行证和阶段时间测量.

  • "auto"与编译器优化有什么关系?"auto"的含义由语言规定,`auto a = 1 + 2;`表示与`int a = 1 + 2;`完全相同. (2认同)
  • 是,.但这似乎与这个问题的主题无关. (2认同)

Dev*_*lar 9

编译器知道表达式(如1 + 2)求值的类型.这就是语言的工作方式 - 两个操作数都是类型,int因此结果也是int如此.有了auto a,您只是告诉编译器"使用初始化表达式的类型".

编译器不必在此处执行任何其他工作或推断.该auto关键字只是让您无法找出表达式并编写正确的类型.(你可能会出错,可能出现意想不到的副作用 - 请参阅这个问题(以及最佳答案),举例说明如何auto避免意外的运行时转换和复制.


auto关键字真正显示出它自己的迭代器:

std::vector< std::string >::const_iterator it = foo.cbegin();
Run Code Online (Sandbox Code Playgroud)

auto it = foo.cbegin();
Run Code Online (Sandbox Code Playgroud)


Zie*_*ezi 5

它是如何工作的:

来自ISO/IEC:

... auto说明符是要推导的类型的占位符(7.1.6.4).其他简单类型说明符指定先前声明的用户定义类型或基本类型之一...

7.1.6.4自动说明符

  1. auto类型说明符表示声明的变量的类型应从其初始化程序推导出,或者函数声明符应包含尾随返回类型.
  2. 在这样的声明符有效的任何上下文中,auto类型说明符可以带有带尾随返回类型的函数声明符.
  3. 否则,从其初始化程序推导出变量的类型.声明的变量的名称不应出现在初始化表达式中.在块,命名空间范围和for-init-statement中声明变量时,允许使用auto; auto应作为decl-specifier-seq中的decl-specifiers之一出现,decl-specifier-seq后面应跟一个或多个initdeclarators,每个initdeclarators都有一个非空的初始化器......

例:

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
Run Code Online (Sandbox Code Playgroud)

它更快:

简单的答案是肯定的,通过使用它可以省略很多类型转换,但是,如果使用不当,它可能成为错误的重要来源.

在Bjarne Stroustrup的一次访谈中,他说auto关键字为编码员和编译器实施者带来了双赢局面.

  • @CIsForCookies很好,可能不是所有的时间,但绝对在所有允许的情况下.在我看来,这是一个伟大的语言功能,应该将其纳入他的"词典". (2认同)