2

嗯,它变得如此混乱。以下 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限定变量的生命周期与程序执行的生命周期相同,为什么我caseswitch-case语句中使用它时仍然会出现错误,应该是一个常量?给出以下错误:

|11|错误:case 标签没有减少为整数常量|

#include<stdio.h>

const int x=2;

int main(void)
{

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

}
4

3 回答 3

4

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

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

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

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

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

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

于 2013-05-16T13:43:52.013 回答
2

我认为您正在将您自己的信息读入那句话。

声明为 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变量。

于 2013-05-17T07:09:14.413 回答
0

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

于 2013-05-16T13:56:57.147 回答