【发布时间】:2019-09-05 11:58:33
【问题描述】:
关于下面的示例,在f1 中,没有出现别名,因为p(void*) 不可访问,而p1 是唯一访问内存的指针。
但是,p1(float*) 和 p2(int*) 之间存在指针别名,位于 f1 之外。
我的问题是,这个别名是否非法,也就是说,严格别名规则是否适用于函数调用?
如果这个例子是有效的,如果 f1 是内联的呢?
void f1(void *p)
{
auto* p1 = static_cast<float*>(p);
*p1 = 1.f;
}
int f2()
{
int x = 1;
auto* p2 = &x;
f1(&x);
*p2 = 1;
return *p2;
}
【问题讨论】:
-
"如果 f1 被内联怎么办" - 内联对严格的别名规则 AFAIK 没有任何影响。无论编译器是否选择内联,代码都需要在别名方面始终正确。
-
这是否违反了严格的别名;另一个考虑:这是否违反对象生命周期?分配对象时,
*p1处是否存在float类型的对象? -
memcpy具有特殊权限并已被优化掉,因此请使用它而不是static_cast来获得优势。 -
@eerorika 我假设一个对象是通过赋值创建的(应该如此),该对象与曾经驻留在此处的任何其他不兼容对象类型无关。其他指针会失效吗?
-
@curiousguy 你能假设一个对象是通过赋值创建的吗? This post 不同意。 对象由定义([basic.def])、新表达式([expr.new])、隐式更改联合的活动成员([class.union])或当创建了一个临时对象([conv.rval], [class.temporary])。
标签: c++ language-lawyer strict-aliasing