为什么gcc不允许将const int作为case表达式?

nal*_*all 28 c compiler-construction const objective-c

我正在考虑这个问题,并开始考虑const ints与#defines,并意识到我实际上并不理解为什么编译器无法解决这个问题.有人可以解释为什么以下代码

const int FOO = 10;

int main(int argc, char** argv)
{
    switch(argc)
    {
        case FOO: { printf("foo\n"); }
        default:  { printf("default\n"); }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是

error: case label does not reduce to an integer constant
Run Code Online (Sandbox Code Playgroud)

我阅读了ISO-C99规范,该规范在6.8.4.2.3中说明

每个case标签的表达式应为整数常量表达式,并且同一switch语句中的两个case常量表达式在转换后不应具有相同的值.

我理解为什么case表达式必须是常量,但不是为什么只有一个文字让编译器(gcc 4.2.1)满意.

dre*_*lax 27

常量表达式与const限定类型值不同,即使从技术上讲,编译器在case语句点处已知该值.

想象一下,如果另一个文件声明extern const int FOO并试图以相同的方式使用它会发生什么.编译器不知道是什么FOO,因为它是在另一个文件中定义的.尽管它具有恒定,但它不是常量表达式.

  • `extern`示例没有任何明确的说明,也没有真正解释任何内容.在C++语言中,您也可以像在C中一样使用`extern`常量,但在C++中,在常量表达式中使用`const int`对象是完全合法的,包括case标签(当然不是`extern`).对原始问题唯一真正的答案是它在历史上就是这样做的.从C的最开始,术语"常量"表示文字数值,而不是"常量"对象.为什么?只是因为. (14认同)
  • 外部问题是一个很好的解释,谢谢.但是有两个问题:为什么C至少不允许本地`static const int`?C++如何应对这一点? (3认同)
  • 啊.谢谢你的外部例子.超级清晰. (2认同)