C和C ++中的Const正确性

我明白const的正确性意味着什么,我的问题不在于const的正确性是什么。 所以我不期待解释或C ++ – FAQ的链接。

我的问题是:

  • C中的const和C ++中的const之间的语义差异是什么?
  • 造成这种差别的原因是什么?

从各自的标准,使差异明确的行情将是很好的。

我经常在C和C ++之间切换,我想知道在这样做的时候应该牢记的重点。

我似乎不记得这些原因(特别感谢,如果你能提供一个推理),但从我的头脑,我可以记得:

  • C ++中的constvariables默认有内部链接,而C中有默认的外部链接;
  • const对象可以在C ++中用作编译时间值,但不能用作C中的编译时间值;
  • 指向string的指针必须是C ++中的char const* ,但在C中,它可以是char*

我错过了什么?

除了你引用的差异之外,还有史蒂夫·杰索普(Steve Jessop)提到的图书馆差异,

 char* p1; char const* const* p2 = &p1; 

在C ++中是合法的,但在C中是不合法的。从历史上看,这是因为C最初允许:

 char* p1; char const** p2 = &p1; 

在标准被采用之前不久,有人意识到这在const安全性中打了一个洞(因为*p2现在可以被分配一个char const* ,这导致p1被分配一个char const* ); 没有真正的时间来深入分析这个问题,C委员会禁止除了顶层const之外的任何额外的const。 (也就是说, &p1可以分配给char **或者char **const ,但不能分配给char const**也不分配给char const* const* 。)C ++委员会做了进一步分析,发现问题只存在当一个const级别后面是一个非常量级别,并且制定了必要的措辞。 (见标准§4.4/ 4)

在C const声明不会产生常量expression式,即在C中,你不能使用一个case标签中的const int对象,作为一个非VLA数组声明中的位域宽度或数组大小(这一切都是可能的C ++)。 另外,const对象在C(C ++中的内部链接)中默认有外部链接。 C ++语言的正确性规则支持以下标准转换

 int **pp = 0; const int *const *cpp = pp; // OK in C++ int ***ppp = 0; int *const *const *cppp = ppp; // OK in C++ 

这些不会在c。

造成这些差异的原因是让我们摆脱了预处理macros,这是Bjarne早期的devise目标之一。

在C我们可能有

  #define MAX_FOOS 10 int foos[MAX_FOOS]; 

在C ++中,我们希望能够编写

  const int max_foos = 10; int foos[max_foos]; 

为了工作, max_foos需要在常量expression式中可用。 它还需要有内部链接,所以定义可以在一个头文件中出现,而不会导致多重定义错误,更重要的是使编译器不会为max_foos分配任何存储max_foos

当C委员会从C ++采用const时,他们并没有对macros进行反感,所以他们不需要这些语义。