虽然编译:
char* p2c;
const char* p2cc = p2c; //fine
因为 lhs 指向类型具有 rhs 指向类型的所有限定符,所以这不会:
char** p2p2c;
const char** p2p2cc = p2p2c; //fail
但这确实:
const char * const * p2cp2cc = p2p2c; //fine
为什么会发生这种情况?
这不起作用:
char** p2p2c;
const char** p2p2cc = p2p2c; //fail
如果允许,您将被允许打破 const 正确性:
const int k = 10;
int *p;
int **pp = &p;
int const **kpp = pp; // Should this be allowed, if so:
*kpp = &k; // fine, kpp promises not to change it
// yet this does p = &k;
// p made no such promise! this is a hidden const_cast!
*p = 5;
如果允许赋值,您将启用设置非 const 指针(中间)以引用常量值,这可能会以不明显的方式导致未定义的行为。通过禁止该操作,类型系统更安全。
但这确实:
const char * const * p2cp2cc = p2p2c; //fine
这很好,因为中间指针是固定的,所以不可能重置中间指针以引用 const 对象并破坏 const-correctness
cdecl在这种情况下真的很有帮助。
const char** p2p2cc = declare p2p2cc as pointer to pointer to const char
和
const char * const * p2cp2cc = declare p2cp2cc as pointer to const pointer to const char
如您所见,第二个版本具有内部和外部指针 const,这意味着它也不能修改。第一个版本具有内部指针 const 和外部非 const,从而破坏了 constnes。
另一方面,这有效:
char** const p = p2p2c;