首页 > 解决方案 > C ++:编译期间的int计算(而不是运行期间)

问题描述

简单的问题:

为什么下面的代码有效?

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

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

谢谢!

标签: c++arrayscompilation

解决方案


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

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

一般来说,这里的计算包括constexprconst类型声明等,它们已经在语言本身的定义中(见常量表达式)。

编译时常量和示例

只需查看示例的输出即可。

编译时 constexpr 和示例

constexpr 说明符声明可以在编译时计算函数或变量的值。


这就是数组的初始化方式,数组声明如下:

noptr 声明符 [ expr(可选) ] attr(可选)

这里expr是:

整数常量表达式 (C++14 前) std::size_t (C++14 起)类型的转换常量表达式,其计算结果大于零

它们都是常量表达式,它说:

一个可以在编译时求值的表达式。

所以,使用所谓的预计算来初始化一个数组是可以的。

这里还有一个后续:还有很多方法可以通过让它们在编译时完成来节省更多计算和时间,它们在上面的链接中显示。


只是提一些不同的东西:至于优化,您可以看到 version 的汇编代码之间的差异,-O0并且-O3在计算从 1 到 100 的总和时,这是一个令人大吃一惊的东西——您会看到结果 5050 在汇编代码中在-O3版本中,它也是一种编译时计算,但不是针对各种情况启用的。


推荐阅读