[英]C++: int calculations during compile time (not during running time)
简单的问题:
为什么下面的代码有效?
int main() {
const int a = 4;
const int b = 16;
const int size = b/a;
int arr[size] = {0,1,2,3};
return 0;
}
我认为静态数组的大小必须在编译时定义,因此只能使用“int”文字。 在上面的代码中,尽管大小是一个计算,但代码可以编译。 这个计算是在编译时完成的吗?
如果是的话,也许我对编译和运行的理解是错误的:编译只是通过语法并将代码转换为机器代码,但不做任何计算......
谢谢!
这个计算是在编译时完成的吗?
是的,编译器为你做了很多优化和计算,你代码中的初始化即使没有任何优化也可以,这是编译器预先计算的结果。
通常,这里的计算包括constexpr
、 const
类型声明等,这些都已经在语言本身的定义中(参见 常量表达式)。
只需查看示例的输出。
constexpr 说明符声明可以在编译时计算函数或变量的值。
这就是数组的初始化方式,数组声明如下:
noptr-declarator [ expr(可选) ] attr(可选)
在这里, expr
是:
整型常量表达式 (C++14 前) std::size_t 类型的转换常量表达式 (C++14 起),其计算结果为大于零的值
它们都是 常量表达式,它说:
可以在编译时计算的表达式。
所以,使用所谓的预计算来初始化一个数组是可以的。
这里还有一个后续:还有很多方法可以通过让它们在编译时完成来节省更多计算和时间,它们显示在上面的链接中。
只是说一些不同的东西:至于优化,在计算1 到 100 的总和时,您可以看到版本-O0
和-O3
的汇编代码之间的差异,这是一个令人震惊的问题——您会看到结果 5050 是在-O3
版本的汇编代码中,它也是一种编译时计算,但并非针对各种情况启用。
我认为静态数组的大小必须在编译时定义,因此只能使用“int”文字。
第一部分为真,但第二部分仅在 c++11 之前为真(您也可以执行const int i = 1 + 2
)。 从 c++11 开始,规则说初始化表达式被评估以查看它是否产生一个常量表达式。
还有一个规则是const
整数类型隐式为constexpr
(即在编译时计算),只要初始化表达式在编译时是可计算的。
所以在这个表达式中:
const int size = b/a;
只要表达式a/b
是常量表达式,就需要在编译时计算变量size
。 由于a
和b
也是用文字初始化的const int
s,因此size
的初始化是一个常量表达式。 (请注意,从任何声明中删除const
将使size
成为非常量表达式)。
因此需要在编译时计算size
(编译器在这件事上别无选择,无论优化如何),因此它可以用作数组维度。
以下是有关其工作原理的完整规则。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.