相关疑难解决方法(0)

-fno-strict-aliasing的性能影响

是否有任何研究或一组基准测试显示由于在GCC中指定-fno-strict-aliasing(或其他编译器中的等效项)而导致的性能下降?

c c++ compiler-construction performance

22
推荐指数
3
解决办法
2万
查看次数

C/C++严格别名,对象生命周期和现代编译器

我面临着关于C++严格别名规则及其可能含义的困惑.请考虑以下代码:

int main() {
  int32_t a = 5;
  float* f = (float*)(&a);
  *f = 1.0f;

  int32_t b = a;   // Probably not well-defined?
  float g = *f;    // What about this?
}
Run Code Online (Sandbox Code Playgroud)

看看C++规范,3.10.10节,从技术上讲,没有一个给定的代码似乎违反了给定的"别名规则":

如果程序试图通过以下类型之一以外的左值访问对象的存储值,则行为未定义:
...合格的访问者类型列表...

  • *f = 1.0f;不会违反规则,因为无法访问存储的值,即我只是通过指针写入内存.我不是从记忆中读书或试图在这里解释一个值.
  • 该行int32_t b = a;不违反规则,因为我通过其原始类型进行访问.
  • float g = *f;出于同样的原因,这条线并没有违反规则.

另一个线程中,成员CortAmmon实际上在响应中提出了相同的点,并且添加了通过写入活动对象而产生的任何可能的未定义行为,如 *f = 1.0f;将在标准的"对象生存期"定义(似乎是对于POD类型来说是微不足道的).

但是:互联网上有大量证据表明上述代码将在现代编译器上产生UB.例如,见这里这里.
在大多数情况下,论证是编译器可以自由考虑&a,f而不是相互混叠,因此可以自由重新安排指令.

现在最大的问题是,如果这种编译器行为实际上是对标准的"过度解释".
唯一一次标准谈论"混叠"的唯一一次是在3.10.10的脚注中,其中明确指出那些是控制混叠的规则.
正如我之前提到的,我没有看到任何上述代码违反了标准,但是很多人(可能还有编译人员)认为它是非法的.

我真的很感激这里的一些澄清.

小更新:
正如成员BenVoigt指出的那样,int32_t …

c++ memory compiler-construction strict-aliasing type-punning

8
推荐指数
1
解决办法
555
查看次数

Do trivial destructors cause aliasing

C++11 §3.8.1 declares that, for an object with a trivial destructor, I can end its lifespan by assigning to its storage. I am wondering if trivial destructors can prolong the object's lifespan and cause aliasing woes by "destroying an object" that I ended the lifespan of much earlier.

To start, something which I know is safe and alias-free

void* mem = malloc(sizeof(int));
int*  asInt = (int*)mem;
*asInt = 1; // the object '1' is now alive, trivial constructor + assignment …
Run Code Online (Sandbox Code Playgroud)

c++ memory destructor c++11

6
推荐指数
1
解决办法
319
查看次数