繁体   English   中英

为什么我们不允许在切换情况下甚至使用全局const限定变量?IBM支持门户网站提示我们可以

[英]Why aren't we allowed to use even global const qualified variables in switch-case?IBM support portal hints we can

呵呵,它变得如此混乱。下面的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开关case语句,这个常数预期它给出以下错误:

| 11 |错误:案例标签未减少为整数常量|

#include<stdio.h>

const int x=2;

int main(void)
{

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

}

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

  1. 简单的编译器实现,
  2. 简单的链接器实现,以及
  3. 高效的代码生成

对于具有内部链接的全局const限定变量,允许它们以常量表达式表示不会太昂贵。 它不必影响上面的项目2和3,而只影响项目1。但是一般来说(可能是外部链接),允许它们意味着:

  1. 编译器需要留出一定的余量(某种方式的重定位),以便不仅解析地址,而且解析链接时该地址的 通常,此问题与标准不需要的一次完整编程/链接时间优化一样困难。 在某些特殊情况下,可能不需要如此强大的解决方案。

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

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

我认为您正在将自己的信息读入该报价中。

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

这是在第二句话说, 没有一个const对象在常量表达式允许,根本没有。

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

这与学前禁止所有狗只没有太大的不同,因为更具攻击性的狗可能会咬伤孩子。


C标准规定了这种行为,因此您实际上不应反对IBM。 他们的文档可能(在某些读数)含糊,但他们做正确的事情。

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

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

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

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

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

问题在于x的值要等到运行时才能确定,但​​要在编译时知道大小写标签表达式(和非VLA数组维),以便编译器可以生成适当的代码。 在编译时,编译器只知道x是标识符并且具有整数类型。 它没有与之关联的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM