C中的常量与C++中的常量

const in C vs const in C++

本文关键字:常量 C++      更新时间:2023-10-16

给定的代码在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】

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

理由:const对象无法分配,因此必须对其进行初始化以保持有用的值。

对原始特征的影响:删除语义定义良好的特征。

转换难度:语义转换。

使用范围:很少。

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

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 vars,并且外部链接没有用处,所以编码器一定是错误地添加了它。

#include<iostream>
using namespace std;
class Test
{
    int value;
    public:
        Test(int v = 0) {value = v;}
        int getvalue() const {return value;}
};
int main(){
    Test t(20);
    cout << t.getvalue();
    return 0;
     
    const double P1 = 68.68;
    cout<<P1<<endl;
    
    int star  = 57;
    int const *pstar = &star;
    cout<<*pstar<<endl;
    
    return 0;
    
}