为什么我们不允许在switch-case中使用甚至全局const限定变量?IBM支持门户网站提示我们可以

时间:2013-05-16 13:31:20

标签: c global-variables switch-statement const constants

嗯它变得如此混乱。以下IBM Support Portal链接似乎表明我们不能将const限定变量用作真实常量的原因是因为它们的生命周期是与程序本身的不一样。似乎只说局部变量作为全局变量与程序具有相同的生命周期。 (IBMLINK)。这就是它的确切含义:

An object that is declared const is guaranteed to remain constant for its lifetime, not throughout the entire execution of the program. For this reason, a const object cannot be used in constant expressions.

但是在下面的程序中,由于const限定变量的生命周期与程序执行的生命周期相同,为什么我在case之后使用它时仍会出现错误 switch-case 语句,其中需要一个常量?它会出现以下错误:

| 11 |错误:案例标签不会缩减为整数常量|

#include<stdio.h>

const int x=2;

int main(void)
{

switch(2)
{
    case 1:
    printf("Hello");
    break;
    case x:
    printf("Hola");
}

}

3 个答案:

答案 0 :(得分:4)

C对常量表达式中可以使用的内容有严格限制的原因是允许:

  1. 简单的编译器实现,
  2. 简单链接器实现,
  3. 高效的代码生成
  4. 对于具有内部链接的全局const限定变量,在常量表达式中允许它们不会太昂贵。它不需要影响上面的第2项和第3项,只需要第1项。但总的来说(可能是外部链接),允许它们意味着:

    1. 编译器需要留出一个限额(重定位某种类型)来解决链接时该地址的地址和。通常,这个问题与标准不需要的完整一次编程/链接时间优化一样困难。在某些特殊情况下,它可能不需要这么强大的解决方案。

    2. 链接器必须能够处理基于重定位的复杂表达式的评估:不仅是地址常量而且是值,从而可以合法地从这些值中推导出所有表达式。

    3. 在switch的情况下,如果编译器不知道case标签的值,则排除了有效的实现(条件的跳转表或二叉树)。这可以通过将所有工作转移到链接时间(一次编程/ LTO)来解决。

答案 1 :(得分:2)

我认为你正在将自己的信息读到该引文中。

  

声明为const的对象保证在其生命周期内保持不变,而不是在整个程序执行期间保持不变。因此,const对象不能用于常量表达式。

在第二句中,在常量表达式中允许 no const对象,完全没有。

它的原因在第一句中给出,虽然我们可以设想可能以这种方式使用const对象的情况,但这绝不会改变确定的第二句。

这与禁止所有狗的学前教育没有多大区别,因为更具攻击性的狗可能会咬伤孩子。


C标准规定了这种行为,因此你不应该对IBM持有这种行为。他们的文档可能含糊不清(在一些读物中),但他们正在做正确的事情。

在(C99)6.8.4.2 The switch statement /3中,我们看到:

  

每个case标签的表达式应该是一个整型常量表达式,并且在同一个switch语句中没有两个case常量表达式在转换后应该具有相同的值。

在同一标准的6.6 Constant expressions /6中,它定义了整数常量表达式:

  

整数常量表达式应具有整数类型,并且只能具有整数常量的操作数,枚举常量,字符常量,结果为整数常量的sizeof表达式,以及作为强制转换的直接操作数的浮点常量。整数常量表达式中的转换运算符只能将算术类型转换为整数类型,除非作为sizeof运算符的操作数的一部分。

如您所见,那里没有提到const变量。

答案 2 :(得分:0)

问题是在运行时间之前不会建立x的值,但需要在编译时知道案例标签表达式(和非VLA数组维度) 时间使编译器可以生成相应的代码。在编译时,编译器知道x的所有内容是它是一个标识符并且具有整数类型;它没有与之相关的值。