为什么Foo**转const Foo**在C++中报错而C中仅给出警告?
问题复现代码
char const c = 'x'; /* 1 */ char *p1; /* 2 */ char const **p2 = &p1; /* 3 */ *p2 = &c; /* 4 */ *p1 = 'X'; /* 5 */
上述代码如果允许第3行的转换成立,会出现明显的const语义漏洞:最终可以通过*p1修改被const修饰的变量c,完全违背const修饰符的设计初衷。
C与C++处理差异的原因
- C语言的类型系统对多层指针的const校验仅做单层判断,规则宽松:C标准仅要求指针赋值时,左值指向的类型的限定符比右值更严格,但该规则不会递归作用到多层指针的嵌套层级。
Foo**转const Foo**时,C只会检查到第一层指向的Foo*和const Foo*不属于兼容类型,不符合限定符规则,但不会直接判定为语法错误,仅抛出警告,把最终的操作合法性交给开发者自行判断,符合C偏向开发自由度的设计取向。 - C的类型系统对多层指针的const校验是递归全层级校验,要求严格:C标准明确规定,多层指针赋值场景下,每一级指针指向的类型的const限定符都要满足左值限定符不弱于右值的要求。
Foo**转const Foo**时,第二层指针指向的Foo*和const Foo*限定符不兼容,因此C直接判定为语法错误,在编译期就拦截可能破坏const语义的不安全操作,符合C偏向类型安全的设计取向。
内容的提问来源于stack exchange,提问作者Ernie Sanderson
相关产品推荐
相关产品推荐

