为什么 const int x = 5; 不是C中的常量表达式吗?

pm1*_*100 4 c constants c99 variable-length-array visual-studio-2019

本以为C不会再给我带来惊喜了,但这却让我大吃一惊。

    const int NUM_FOO = 5;
    ....

    int foo[NUM_FOO];
==>error C2057: expected constant expression
Run Code Online (Sandbox Code Playgroud)

我的 C++ 经验让我在内部#define尽可能地反对。所以这真是一个惊喜。VS2019,使用/TC编译。我认为 C99 无论如何都允许可变大小的数组。

  1. 任何人都可以解释为什么会发生拒绝,因为编译器在编译时肯定知道数组的大小?

  2. C99不是允许可变大小数组吗?

Kei*_*son 7

在 C 语言中,这个声明:

const int NUM_FOO = 5;
Run Code Online (Sandbox Code Playgroud)

不构成NUM_FOO常量表达式。

要记住的事情(是的,这有点违反直觉)是这const并不意味着constant粗略地说,常量表达式是可以在编译时计算的表达式(如2+242)。类型const限定符,尽管它的名字显然源自英语单词“constant”,但它真正的意思是“只读”。

例如,考虑一下这些是完全有效的声明:

const int r = rand();
const time_t now = time(NULL);
Run Code Online (Sandbox Code Playgroud)

justconst意味着你不能修改它们初始化后的r值。now这些值显然要等到执行时才能确定。

(C++ 有不同的规则。它确实生成NUM_FOO常量表达式,并且constexpr为此目的添加了该语言的更高版本。C++ 不是 C。)

至于可变长度数组,是的,C 在 C99 中添加了它们(并在 C11 中使它们成为可选)。但正如jamesdlin 的回答所指出的,VS2019 不支持 C99 或 C11。

(C++ 不支持 VLA。这:const int NUM_FOO = 5; int foo[NUM_FOO];在 C99 和 C++ 中都是合法的,但原因不同。)

如果要定义类型为的命名常量int,可以使用enum

enum { NUM_FOO = 5 };
Run Code Online (Sandbox Code Playgroud)

或老式宏(不限于 type int):

#define NUM_FOO 5
Run Code Online (Sandbox Code Playgroud)

jamesdlin 的答案dbush 的答案都是正确的。我只是添加更多背景信息。