C++ C++;:通过union绕过严格的别名,然后使用_restrict extension
我想知道是否有可能根据具体设计的情况定制严格的别名要求,同时仍然保留一般的严格别名或分别保留-O2/-O3优化。C++ C++;:通过union绕过严格的别名,然后使用_restrict extension,c++,memory,casting,strict-aliasing,restrict-qualifier,C++,Memory,Casting,Strict Aliasing,Restrict Qualifier,我想知道是否有可能根据具体设计的情况定制严格的别名要求,同时仍然保留一般的严格别名或分别保留-O2/-O3优化。 更准确地说,在需要的情况下,可以使用匿名联合绕过严格的别名(如所指出的和所述): 现在我想知道,对通过这种强制转换获得的指针使用\u restrict是否会在编译器中重新启用别名优化(或者这样一个指针及其所有副本是否会一直被视为潜在的别名)。像这样: void bar(float* __restrict a, float* __restrict b) { // Do somet
更准确地说,在需要的情况下,可以使用匿名联合绕过严格的别名(如所指出的和所述): 现在我想知道,对通过这种强制转换获得的指针使用
\u restrict
是否会在编译器中重新启用别名优化(或者这样一个指针及其所有副本是否会一直被视为潜在的别名)。像这样:void bar(float* __restrict a, float* __restrict b) {
// Do something with a and b assuming they don't overlap.
}
void baz(float* c) { /* Do something with c... */ }
void foo() {
int32_t* buffer = new int32_t[1000];
// Do something with buffer...
float* bufCast1 = PTR_CAST(float, buffer);
float* bufCast2 = PTR_CAST(float, buffer + 500);
// Can the arguments be successfully __restrict-ed in this case?
bar(bufCast1, bufCast2);
// Also, would bufCast1 be treated as potentially aliasing inside of baz()?
baz(bufCast1);
}
几乎所有你提到的不是C++,而是一些编译器扩展或其他。因此,请查阅编译器的文档并研究生成的机器代码。这就是说,
\uuu restrict
是您的承诺,指针不会指向重叠的数据。通过联合使用别名得到广泛支持,从技术上讲,它是一种扩展,但在大多数情况下是可移植的。\uu restrict
显然是一个扩展,但也得到了广泛支持。问题是\u restrict
是否通常会覆盖编译中的任何其他别名信息,或者在遇到基于联合的强制转换时,一旦编译器自己的别名分析触发了红旗,它是否会变得无用。编译器如何知道?如果bar
位于一个单独的TU中,编译器必须相信您没有欺骗它。但正如我所说,最简单的方法就是检查机器代码是如何产生的。嗯,是的,是的,有道理。我想clang可以进行链接时间优化,这样它可能可以在TUs中解决这个问题。@RafaelSpring:鉴于\uu restrict
将使编译器有权假设两个指针即使是同一类型的指针也不会有别名冲突,为什么编译器不应该在其他情况下应用相同的假设,其中类型不会排除别名,但\u restrict
限定符会排除别名?
void bar(float* __restrict a, float* __restrict b) {
// Do something with a and b assuming they don't overlap.
}
void baz(float* c) { /* Do something with c... */ }
void foo() {
int32_t* buffer = new int32_t[1000];
// Do something with buffer...
float* bufCast1 = PTR_CAST(float, buffer);
float* bufCast2 = PTR_CAST(float, buffer + 500);
// Can the arguments be successfully __restrict-ed in this case?
bar(bufCast1, bufCast2);
// Also, would bufCast1 be treated as potentially aliasing inside of baz()?
baz(bufCast1);
}