严格别名规则是否适用于函数调用?
Does the strict-aliasing rules apply across function calls?
关于下面的示例,在 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;
}
无论您将指针复制多少次或将其传递到其他地方或转换多少次,决定因素始终是该位置实际存储的内容。
在您的情况下,唯一重要的是 static_cast
的参数是否实际上是 float
的地址,而事实并非如此。
适合在具有已发布 ABI 的平台上进行 low-level 编程的编译器将提供一种强制以与该 ABI 一致的方式执行函数调用的方法,这反过来会强制 "strict aliasing violations" 跨越 function-call 边界的要处理 "in a documented fashion characteristic of the environment"。这种支持是 "popular extension",标准的作者认为不在他们的管辖范围内。设计和配置为适合 low-level 编程的编译器将支持此类结构,而不管标准是否需要它,而那些未设计和配置为适合此类目的的编译器不应用于他们。
关于下面的示例,在 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;
}
无论您将指针复制多少次或将其传递到其他地方或转换多少次,决定因素始终是该位置实际存储的内容。
在您的情况下,唯一重要的是 static_cast
的参数是否实际上是 float
的地址,而事实并非如此。
适合在具有已发布 ABI 的平台上进行 low-level 编程的编译器将提供一种强制以与该 ABI 一致的方式执行函数调用的方法,这反过来会强制 "strict aliasing violations" 跨越 function-call 边界的要处理 "in a documented fashion characteristic of the environment"。这种支持是 "popular extension",标准的作者认为不在他们的管辖范围内。设计和配置为适合 low-level 编程的编译器将支持此类结构,而不管标准是否需要它,而那些未设计和配置为适合此类目的的编译器不应用于他们。