简体   繁体   English

C 中的 const 与 C++ 中的 const

[英]const in C vs const in C++

The given code compiles in C but fails in C++.给定的代码在 C 中编译,但在 C++ 中失败。

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

What is the rationale and the reason behind the change from C to C++?从 C 到 C++ 的转变背后的基本原理和原因是什么?

See the spec, in the compatibility appendix C.1.6: 请参阅兼容性附录C.1.6中的规范:

7.1.6 [see also 3.5] 7.1.6 [另见3.5]

Change: const objects must be initialized in C++ but can be left uninitialized in C 更改: const对象必须在C ++中初始化,但可以在C中保持未初始化

Rationale: A const object cannot be assigned to so it must be initialized to hold a useful value. 基本原理:无法分配const对象,因此必须初始化它以保存有用的值。

Effect on original feature: Deletion of semantically well-defined feature. 对原始特征的影响:删除语义明确定义的特征。

Difficulty of converting: Semantic transformation. 转换难度:语义转换。

How widely used: Seldom. 如何广泛使用:很少。

Note that there is a legitimate use of an uninitialized, const-qualified object of automatic storage duration: its address can be taken and used as a unique key for labeling recursion levels in a recursive function. 请注意,合法使用自动存储持续时间的未初始化的const限定对象:可以获取其地址并将其用作在递归函数中标记递归级别的唯一键。 This is somewhat obscure, but worth noting. 这有点模糊,但值得注意。 C makes this use efficient, while C++ requires you waste time and code size on initializing it. C使这种使用效率很高,而C ++则需要在初始化时浪费时间和代码大小。 (In theory the compiler could perhaps determine that the value is never used and optimize out the initialization, but since you're passing around a pointer, that would be rather difficult to prove.) (理论上,编译器可能会确定该值从未使用过并优化了初始化,但由于您传递的是指针,因此很难证明。)

The const keyword was introduced to C in C89 in 1989, but had been with C++ since its creation in 1983. So it was "backported" from C++ to C. const关键字于1989年在C89中引入C,但自1983年创建以来一直使用C ++。因此它从C ++“反向移植”到C.

Initialization semantics are generally different in C and C++. 初始化语义在C和C ++中通常是不同的。 Although most of the time they "just do the thing you expect", there are cases where the differences become quite important. 虽然大多数时候他们“只做你期望的事情”,但有些情况下差异变得非常重要。 C++ really isn't a superset of C after all. 毕竟C ++真的不是C的超集。

For example, in C++ you can't: 例如,在C ++中你不能:

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

But that is perfectly legal in C. 但这在C语言中完全合法。

The ISO standard says (in 8.5 [dcl.init] paragraph 9 ): ISO标准说(在8.5 [dcl.init] 第9段中 ):

If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; 如果没有为对象指定初始化程序,并且该对象是(可能是cv限定的)非POD类类型(或其数组),则该对象应默认初始化; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor. 如果对象是const限定类型,则底层类类型应具有用户声明的默认构造函数。

if you try the same example after modifying to this: 如果您在修改为此后尝试相同的示例:

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

it will get compiled. 它会被编译。 So this self explains the need of enforcing this error to c++, declaring const vars without initializing and extern linkage is of no use, so coder must have added it by mistake. 因此,这个自我解释了将此错误强制执行到c ++的必要性,在没有初始化的情况下声明const变量并且extern链接是没有用的,因此编码器必须错误地添加它。

#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;
    
}

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

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