【问题标题】:Why doesn't gcc allow a const int as a case expression?为什么 gcc 不允许 const int 作为 case 表达式?
【发布时间】:2010-12-15 07:47:14
【问题描述】:

我在看这个SO question 并开始考虑 const ints 与 #defines 并意识到我实际上并不明白为什么编译器不能处理这个问题。有人可以解释一下为什么下面的代码

const int FOO = 10;

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

结果

error: case label does not reduce to an integer constant

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

每个case标签的表达 应该是一个整数常量 表达和没有两种情况 相同的常量表达式 switch 语句应具有相同的 转化后的价值。

我明白为什么 case 表达式必须是常量,但不明白为什么只有文字才能让编译器 (gcc 4.2.1) 满意。

【问题讨论】:

  • 有趣的是,代码似乎在 gcc-4.3.4 上编译和运行得很好:ideone.com/n1bmIb 编辑:啊.. 但只能作为 C++,而不是 C。

标签: c objective-c compiler-construction constants


【解决方案1】:

常量表达式与 const 限定类型值不同,尽管从技术上讲,编译器在 case 语句的位置知道该值。

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

【讨论】:

  • extern 示例没有说明任何内容,也没有真正解释任何内容。在 C++ 语言中,您还可以声明一个 extern 常量,就像在 C 中一样,但在 C++ 中,在常量表达式中使用 const int 对象是完全合法的,包括大小写标签(当然不是 extern 的)。对原始问题的唯一真正答案是,它在历史上就是这样做的。从一开始在 C 中,术语“常量”意味着文字数值,而不是 const 对象。为什么?只是因为。
  • 嗯,extern 示例是我想不出但编译器无法处理的示例。不过,您的评论很有价值。谢谢。
  • 那么,有没有办法避免在 case 语句中使用幻数?
  • @Harkonian:您可以使用预处理器宏,即#define FOO 10
  • 外部问题是一个很好的解释谢谢。但是有两个问题:为什么 C 至少不允许本地 static const int 这样做? C++ 是如何处理这个问题的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-11
  • 2018-11-29
  • 1970-01-01
  • 2010-11-30
  • 1970-01-01
  • 2016-10-25
  • 2011-10-09
相关资源
最近更新 更多