C中的const与C ++中的const

给定的代码在C中编译但在C ++中失败。

int main() { const int x; /* uninitialized const compiles in C but fails in C++*/ } 

从C到C ++的变化背后有什么理由和原因?

请参阅兼容性附录C.1.6中的规范:

7.1.6 [另见3.5]

更改: const对象必须在C ++中初始化,但可以在C中保持未初始化

基本原理:无法分配const对象,因此必须初始化它以保存有用的值。

对原始特征的影响:删除语义明确定义的特征。

转换难度:语义转换。

如何广泛使用:很少。

请注意,合法使用自动存储持续时间的未初始化的const限定对象:可以采用其地址并将其用作标记递归函数中递归级别的唯一键。 这有点模糊,但值得注意。 C使这种使用变得高效,而C ++则需要在初始化时浪费时间和代码大小。 (理论上,编译器可能会确定该值从未使用过并优化了初始化,但由于您传递的是指针,因此很难certificate。)

const关键字于1989年在C89中引入C,但自1983年创建以来一直使用C ++。所以它从C ++“反向移植”到C.

初始化语义在C和C ++中通常是不同的。 虽然大多数时候他们“只做你想要的事情”,但有些情况下差异变得非常重要。 毕竟C ++确实不是C的超集。

例如,在C ++中你不能:

 goto x; int i = 3; x: puts("Hello, world"); 

但这在C语言中是完全合法的。

ISO标准说(在8.5 [dcl.init] 第9段中 ):

如果没有为对象指定初始化程序,并且该对象是(可能是cv限定的)非POD类类型(或其数组),则该对象应默认初始化; 如果对象是const限定类型,则底层类类型应具有用户声明的默认构造函数。

如果您在修改为此后尝试相同的示例:

 int main() { /*Unless explicitly declared extern, a const object does not have external linkage and must be initialized*/ extern const int x; return 0; } 

它会被编译。 所以这个自我解释了将此错误强制执行到c ++的必要性,在没有初始化的情况下声明const变量并且extern链接是没有用的,因此编码器必须错误地添加它。