当前位置: 首页 > 知识库问答 >
问题:

“auto”说明符在编译时间上是否较慢?

夏侯博
2023-03-14

由于C11,我们可以使用autoA=12而不是intA=12,编译器可以自己推断a的类型。它是如何工作的?编译时(更多操作)是否比自己声明类型慢?

共有3个答案

仇浩旷
2023-03-14

来自ISO/IEC:

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

  1. 自动类型说明符表示声明的变量类型应从其初始化器推导,或者函数声明符应包括尾随返回类型。
  2. 自动类型说明符可能会出现在任何上下文中,在这种声明符有效的情况下,带有尾随返回类型的函数声明符。
  3. 否则,从变量的初始化器推导变量的类型。被声明的变量的名称不应出现在初始化表达式中。当在块、命名空间范围和for-init-语句中声明变量时,允许使用自动;自动应显示为decl-说明符-seq中的一个decl-说明符,decl-说明符-seq后跟一个或多个init声明符,每个都应该有一个非空的初始化器...

例子:

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

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

在Bjarne Stroustrup的一次采访中,他说auto关键字为编码人员和编译器实现人员带来了双赢的局面。

盖夕
2023-03-14

编译器知道表达式(如1 2)计算的类型。这正是语言的工作方式--两个操作数都是类型int,因此结果也是int。使用autoa,您只是告诉编译器使用初始化表达式的类型。

编译器不必在这里做任何额外的工作或推导。auto关键字只是让您不必计算表达式和编写正确的类型。(您可能会出错,可能会有意想不到的副作用——请参阅这个问题(以及最上面的答案),了解如何自动避免意外运行时转换和复制的示例。

自动关键字确实是通过迭代器来实现的:

std::vector< std::string >::const_iterator it = foo.cbegin();

auto it = foo.cbegin();
连文栋
2023-03-14

auto要求C11编译器进行一些有限类型的类型推断(如果您想要一些更性感的类型推断语言,请查看Ocaml)。但是开销只是编译时的。

如果更换自动a=1 2 inta=12 (两者含义相同,请参阅simplicis的答案),如果您要求编译器进行优化(甚至可能不要求优化),您可能会得到相同的机器代码。另见此。

如果使用GCC,试着编译一个小的c11foo。用g-Wall-fverbose asm-O-sfoo抄送file。抄送并查看(使用编辑器)生成的foo。s汇编程序文件。您将在生成的代码中看不到任何差异(但是汇编程序文件可能会有轻微的更改,例如,由于调试信息等元数据的原因)

如果您担心编译时间变慢,我想使用auto并不是一个决定性的因素(可能,重载在编译时间上的代价会更高)。C 11几乎被设计成实际需要大量优化(特别是复杂的内联和不断折叠以及死代码消除),其“解析”(尤其是头包含和模板扩展)成本高昂。

使用make-j(可能还有ccachedistcc)预编译头和并行构建可能有助于提高总体编译时间,而不仅仅是避免auto

如果您想要系统地避免auto(特别是在std::map之类的循环范围内)

如果使用GCC,您可能会将-ftime报告传递给g,并获取有关各种GCC过程和阶段的时间度量。

 类似资料:
  • 编译单个 package: make package/<pkg_name>/compile 清楚单个 package: make package/<pkg_name>/clean 可以这样顺序执行 clean 和 compile: make package/<pkg_name>/{clean,compile}

  • 编译 uboot: make package/uboot-leo/compile 清除 uboot: make package/uboot-leo/clean 拷贝 uboot 到编译生成目录 make package/uboot-leo/install 顺序执行 uboot 的 clean,compile,install make package/uboot-leo/{clean,comp

  • 修改公共的 kernel 配置: make kernel_menuconfig 编译 kernel: make target/linux/compile 清除 kernel: make target/linux/clean 拷贝 kernel 到编译生成目录 make target/linux/install 顺序执行 kernel 的 clean,compile,install make

  • 拷贝默认配置: cp configs/leo_gx8010_ssd_1v_defconfig .config 加载默认配置: make defconfig 修改 openwrt 配置: make menuconfig 编译: make 如果想加快编译速度,请加-j 参数使用多线程编译 如果想查看详细编译信息,请加 V=s 参数打印编译 log 清理 packages,kernel,uboo

  • git clone https://github.com/Meituan-Dianping/octo-rpc.git octo-rpc 2.构建Jar包 环境要求: Java version >= 1.7 Maven version >= 3.0 切换到dorado目录 cd octo-rpc/dorado 本地install,执行后在本地仓库~/.m2/repository/com/meit

  • 安装G01的时候,G01会自动适配nginx版本,使用我们已经预编译好的包含防护模块的nginx文件替换掉您当前系统中使用的nginx文件。卸载时,会将备份的系统原始nginx文件替换回来。因此,G01可保护使用nginx搭建的网站,开创了这个领域的先河。 当nginx更新或用户的nginx添加(--add-moudel)了第三方模块时需要用户手工加载G01的防护模块进行防护。通常在安装时G01会