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进行反感,所以他们不需要这些语义。