是否可以将int **和const int **替换为别名?

我的理解是这样的事情是可以的:

const int ci = 42; const int *cip = &ci; int *ip = (int *)cip; int j = *ip; 

那这个呢?

 const int ci = 42; const int *cip = &ci; const int **cipp = &cip; int **ipp = (int **)cipp; int j = **ipp; 

表达式*ippint *类型的左值,但是它用于访问有效类型为const int *的对象。 (即, cip )。

根据标准的字母,它是严格的别名违规:允许的别名类型列表不包括别名T *作为const T * ,反之亦然。

最接近的例外是这一个:(C11 6.5 / 6摘录)

  • 与对象的有效类型兼容的类型的限定版本

“合格版本”由C11 6.2.5 / 26明确界定:

每个非限定类型都有几个类型的 限定版本 ,对应于constvolatilerestrict限定符中的一个,两个或全部三个的组合。 类型的限定或非限定版本是属于相同类型类别且具有相同表示和对齐要求的不同类型。 派生类型不是由派生类型的限定符(如果有)限定的。

所以例外是T可能被别名为const T ,反之亦然,但是对于指向别名类型的指针没有类似的exception。 const T *不是const T *合格版本


然而,当然有脚注:

此列表的目的是指定对象可能或可能不具有别名的情况

我不能说规则的意图是const T *T *是否可以共存。 我似乎不清楚,如果它不是可混淆的,那么指定T *const T *具有“相同的表示和对齐要求”(6.2.5 / 28)的目的是什么。