繁体   English   中英

C++:编译时的 int 计算(不是运行时)

[英]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”文字。 在上面的代码中,尽管大小是一个计算,但代码可以编译。 这个计算是在编译时完成的吗?

如果是的话,也许我对编译和运行的理解是错误的:编译只是通过语法并将代码转换为机器代码,但不做任何计算......

谢谢!

这个计算是在编译时完成的吗?

是的,编译器为你做了很多优化和计算,你代码中的初始化即使没有任何优化也可以,这是编译器预先计算的结果。

通常,这里的计算包括constexprconst类型声明等,这些都已经在语言本身的定义中(参见 常量表达式)。

编译时常量和示例

只需查看示例的输出。

编译时 constexpr 和示例

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 由于ab也是用文字初始化的const int s,因此size的初始化是一个常量表达式。 (请注意,从任何声明中删除const将使size成为非常量表达式)。

因此需要在编译时计算size (编译器在这件事上别无选择,无论优化如何),因此它可以用作数组维度。

以下是有关其工作原理的完整规则

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM