严格别名规则是否适用于函数调用?

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 编程的编译器将支持此类结构,而不管标准是否需要它,而那些未设计和配置为适合此类目的的编译器不应用于他们。