从指向const的指针中删除const是否遵循C中的严格别名,并引用同一个对象?

Ste*_*sop 14 c const strict-aliasing language-lawyer

C中的以下代码是否定义了行为?

int main() {
    const int i = 0;
    return *(int*)(&i);
}
Run Code Online (Sandbox Code Playgroud)

我问,因为6.5/7列出了"与对象的有效类型兼容的类型的合格版本"作为有效别名.但是对象的有效类型是const int,我认为不是int合格版本const int(尽管反之亦然).既不是intconst int兼容(6.7.3/10).

此外,6.3.2.3/2表示您可以通过添加限定符来转换指针类型,并且结果指针是相等的.6.3.2.3/7表示你可以转换任何两种指针类型(因此(int*)(&i)允许转换本身).但是并没有说结果指针指的是同一个对象,甚至它是相等的.它说的是它可以转换回原始类型(在这种情况下const int*).也就是说,即使别名是合法的,我也不清楚标准是否保证我的指针转换确实会导致指向的指针i.

那么,标准是否实际定义了我的代码的行为,如果是,那么这个定义在哪里?

我知道代码在实践中有效.我想到了一个不起作用的假设(和奇怪)实现.我可以问这个实现是否符合标准(如果不符合,它违反了哪个部分),但如果还有其他方面,我想象的实现无法符合,我不想浑水.如果有人认为这将有助于他们回答问题,我将描述实施.

caf*_*caf 8

至少暗示它的工作原理是§6.7.3p5:

如果尝试通过使用具有非const限定类型的左值来修改使用const限定类型定义的对象,则行为是未定义的.如果尝试通过使用具有非volatile限定类型的左值来引用使用volatile限定类型定义的对象,则行为未定义.

请注意,对于volatile描述的类型,它表示引用,但对于const限定类型,它只是说修改,这意味着非修改访问是正常的("证明规则的例外 ").

在我看来,你可能已经发现了标准中的缺陷.

  • @Christoph:我同意这是严格阅读别名规则的结果,但我的观点是我不认为这是*预期的*效果,因为它会使我引用的规范段落完全没有实际意义,并且没有解释为什么不同的措辞用于其中的常数和挥发性. (3认同)