int** 和 const int** 可以别名吗?

Is it okay for int** and const int** to alias?

据我了解,这样的事情是可以的:

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;

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

根据标准的规定,这是一个严格的别名违规:允许使用别名的类型列表不包括别名 T *const T *,反之亦然。

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

  • a qualified version of a type compatible with the effective type of the object

"qualified version"由C11 6.2.5/26明确定义:

Each unqualified type has several qualified versions of its type, corresponding to the combinations of one, two, or all three of the const, volatile, and restrict qualifiers. The qualified or unqualified versions of a type are distinct types that belong to the same type category and have the same representation and alignment requirements. A derived type is not qualified by the qualifiers (if any) of the type from which it is derived.

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


当然还有脚注:

The intent of this list is to specify those circumstances in which an object may or may not be aliased

我不能说这条规则的目的是为了让 const T *T * 可以使用别名。我似乎不清楚指定 T *const T * 具有 "the same representation and alignment requirements" (6.2.5/28) 的目的是什么,如果它不可别名的话。