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

Tav*_*nes 8 c const strict-aliasing undefined-behavior language-lawyer

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

const int ci = 42;
const int *cip = &ci;
int *ip = (int *)cip;
int j = *ip;
Run Code Online (Sandbox Code Playgroud)

那这个呢?

const int ci = 42;
const int *cip = &ci;
const int **cipp = &cip;
int **ipp = (int **)cipp;
int j = **ipp;
Run Code Online (Sandbox Code Playgroud)

M.M*_*M.M 5

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

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

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

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

C11 6.2.5/26明确规定了"合格版本":

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

所以异常是 T可能是别名,const T反之亦然,但是对于指向别名类型的指针没有类似的异常. const T *是不是一个合格的版本T *.


然而,当然有脚注:

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

我不知道该规则的意图是否是const T *T */或是否可以共存.对我来说,似乎不清楚指明这一点的目的是什么,T *并且const T *具有"相同的表示和对齐要求"(6.2.5/28),如果它不是可混淆的.