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

时间:2017-07-16 01:08:53

标签: c const language-lawyer undefined-behavior strict-aliasing

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

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;

1 个答案:

答案 0 :(得分:5)

表达式verify( fragment ).showAddress(any(), anyBoolean()); *ipp类型的左值,但它用于访问有效类型int *的对象。 (即const int *)。

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

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

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

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

  

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

所以例外是restrict可能别名为T,反之亦然,但是对于指向别名类型的指针没有类似的异常。 const T不是const T *限定版

然而,当然有脚注:

  

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

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