【问题标题】:Why in C a const object is not a compile-time constant expression? [duplicate]为什么在 C 中 const 对象不是编译时常量表达式? [复制]
【发布时间】:2017-02-25 01:02:00
【问题描述】:

在 C 中,const 限定符使对象只读,但不是常量表达式。例如,不可能使用const int 变量来为数组维度:

const int n = 10;
int arr [n];         /* Compile-time error */

这是什么技术原因?编译器在编译时不可能知道对象实际上有一个常量值吗?


我不认为我的问题是Can a const variable be used to declare the size of an array in C?确切重复 因为我不是在问这是否可能(在我的问题中明确说明不是),而是技术原因这是不可能的。


在下面奥拉夫的评论,this answer 和一些沉思之后,我会尝试以这种方式总结和回答我的问题:

在 C 中,const 对象不是编译时常量,因为它可能违反这两个要求:

首先,可以在运行时初始化const对象,如下所示:

int i;
scanf ("%d", & i);
const int n = i;

所以这里我们违反了“在编译时已知”的要求。

其次,正如Olaf 所指出的,const 限定符意味着程序本身 在声明初始化之后不会修改对象的值。但是内存中对象的值仍然可以被程序本身之外的一些其他实体修改,所以这里我们不保证实际常量的要求。

如果此答案不正确或不完整,请批评。

【问题讨论】:

  • 你用的是什么编译器?我刚刚在 GCC 4.8.2 中尝试过,它可以编译
  • @UnholySheep:它将在函数范围内工作,因为它定义了一个 VLA(可变长度数组)。您将无法初始化该数组。它不能在标准 C 的全局范围内工作——VLA 不能在全局(文件)范围内定义。也许 GCC 允许它作为一个扩展,但请注意它是一个扩展。
  • “在 C 中, const 限定符使对象只读” - 不,它没有!只是程序员向编译器保证他不会在其声明的范围内更改该对象。
  • @Olaf:感谢您的更正,我认为您在这里达到了一个基本点

标签: c expression constants compile-time


【解决方案1】:

这样做的一个技术原因可能是,当初始化程序不是常量表达式时,这样的声明甚至是有效的,所以这是从初始化程序推导出来的语义属性。

那么,按照目前的规则,没有办法在头文件中包含这样的东西,以便在文件范围内声明和定义。任何对象只能有一个定义,多个对象文件不能链接在一起。

有一些想法可以在下一个 C 版本中改善这种情况。

【讨论】:

  • “有一些想法可以为下一个 C 版本改进这种情况。” - 你有支持这个的参考吗?
  • @Olaf:来自WG14 网站的 PrePittsburgh2016 邮件中的文件 N2067“寄存器大修”——作者是“Jens Gustedt”。
  • @JonathanLeffler 谢谢。顺便提一句。我已经在缺陷报告中看到了这个名字,这并不奇怪 ;-)
猜你喜欢
  • 2014-04-20
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
  • 1970-01-01
  • 2013-10-16
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
相关资源
最近更新 更多