在C++中,严格别名规则中的"访问"是什么意思?

M.M*_*M.M 12 c++ strict-aliasing language-lawyer

3.10/10说:

如果程序试图通过以下类型之一以外的glvalue 访问对象的存储值,则行为未定义:

但是,术语"访问"并未在任何地方定义.在这种情况下,它是指,读或修改


在C标准中,它明确地定义为读取或修改.但是在C++ 11中,它似乎在不同的时间使用不同的含义,例如:

1.9/8:

严格根据抽象机器的规则来评估对volatile对象的访问.

显然,这是为了阅读或修改,但在许多其他地方,如1.10/24:

  • 访问或修改易失性对象,或

它被用作好像只是意味着阅读.

T.C*_*.C. 4

它必须意味着读和写,否则规则就没有多大意义。考虑http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html中的示例:

float *P;
void zero_array() {
   int i;
   for (i = 0; i < 10000; ++i)
       P[i] = 0.0f;
}
Run Code Online (Sandbox Code Playgroud)

memset仅当编译器可以假设没有任何P[i]别名时,上面的示例代码才能优化为 a P。但是考虑一个世界,其中仅从不允许的左值读取才是 UB,那么即使某些P[i]别名存在,上面的代码也不会调用 UB - 例如,如果有人这样做,因为所有读取都是完全合法的 - 它们都使用左值表达式。PiP = (float *) &P;PP


编辑CWG 第 1531 期问题直接切中要点。该问题于 2013 年 4 月转入 DR(缺陷报告)状态,但无论出于何种原因,该决议并未应用于工作文件。