Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
编译器进行的优化什么时候可以破坏我的C++;密码? P>编译器优化后,如果没有执行这些优化,我的C++代码会出现错误的行为吗?例如,在某些情况下不使用volatile可能会导致程序行为不正确(例如,不从内存中重新读取变量的值,而是只读取一次并将其存储在寄存器中)。但是,在打开“最激进的优化”标志,然后想知道为什么程序不再工作之前,还有其他应该知道的陷阱吗?_C++_Optimization - Fatal编程技术网

编译器进行的优化什么时候可以破坏我的C++;密码? P>编译器优化后,如果没有执行这些优化,我的C++代码会出现错误的行为吗?例如,在某些情况下不使用volatile可能会导致程序行为不正确(例如,不从内存中重新读取变量的值,而是只读取一次并将其存储在寄存器中)。但是,在打开“最激进的优化”标志,然后想知道为什么程序不再工作之前,还有其他应该知道的陷阱吗?

编译器进行的优化什么时候可以破坏我的C++;密码? P>编译器优化后,如果没有执行这些优化,我的C++代码会出现错误的行为吗?例如,在某些情况下不使用volatile可能会导致程序行为不正确(例如,不从内存中重新读取变量的值,而是只读取一次并将其存储在寄存器中)。但是,在打开“最激进的优化”标志,然后想知道为什么程序不再工作之前,还有其他应该知道的陷阱吗?,c++,optimization,C++,Optimization,除了您提到的情况外,多线程代码中的计时可能会发生变化,使得看起来有效的不再有效。局部变量的位置可能会有所不同,因此在调试过程中会出现有害行为,如内存缓冲区溢出,但在发布、优化或非优化过程中不会发生,反之亦然。但所有这些都是已经存在的bug,只是通过修改编译器选项暴露出来的 这是假设编译器的优化器中没有bug。我只在浮点数学中遇到过它。有时,对速度的优化可能会稍微改变答案。当然,对于浮点数学,“正确”的定义并不总是那么容易,因此您必须运行一些测试,看看优化是否达到了预期效果。优化不一定会使结果出错

除了您提到的情况外,多线程代码中的计时可能会发生变化,使得看起来有效的不再有效。局部变量的位置可能会有所不同,因此在调试过程中会出现有害行为,如内存缓冲区溢出,但在发布、优化或非优化过程中不会发生,反之亦然。但所有这些都是已经存在的bug,只是通过修改编译器选项暴露出来的


这是假设编译器的优化器中没有bug。

我只在浮点数学中遇到过它。有时,对速度的优化可能会稍微改变答案。当然,对于浮点数学,“正确”的定义并不总是那么容易,因此您必须运行一些测试,看看优化是否达到了预期效果。优化不一定会使结果出错,只是不同而已


除此之外,我从未见过任何优化会破坏正确的代码。编译器编写人员非常聪明,他们知道自己在做什么。

编译器优化不应该影响程序的可观察行为,因此理论上,您不需要担心。在实践中,如果您的程序偏离了未定义的行为,任何事情都可能已经发生,因此,如果您的程序在启用优化时出现故障,那么您只是暴露了现有的bug——并不是优化导致了故障


一个常见的优化点是返回值优化(RVO)和命名的返回值优化(NRVO),这基本上意味着从函数返回值的对象直接在接收它们的对象中构造,而不是制作副本。这会调整构造函数、复制构造函数和析构函数调用的顺序和数量,但通常在正确编写这些函数的情况下,在行为上仍然没有明显的差异。

我最近刚刚看到(在C++0x中)允许编译器假定某些类的循环将始终终止(以允许优化). 我现在找不到参考资料,但如果我能找到,我会尝试链接它。这可能会导致可观察到的程序更改。

我没有确切的细节(也许其他人可以插话),但我听说如果循环计数器变量为char/uint8_t类型(在gcc上下文中,即),则循环展开/优化会导致错误。

使用gcc可能会遇到严格的别名问题。据我所知,在某些版本的gcc(GCC4.4)中,它会通过优化自动启用。这个网站在解释严格的别名规则方面做得很好。

只是假设优化器曾经破坏过你的代码。这不是它的本意。如果你观察问题,那么自动地考虑无意UB。< /P>
是的,线程可能会破坏您习惯的假设。您无法从语言或编译器获得任何帮助,尽管这正在改变。你要做的不是在volatile上撒尿,而是使用一个好的线程库。当两个或多个线程都可以接触变量时,可以使用它的一个同步原语。尝试自己的捷径或优化这一点是一个单向线程进入线程地狱。< /P> < P>在元级别,如果你的代码使用依赖于基于C++标准的未定义方面的行为,符合编译器的标准可以自由地破坏你的C++代码(正如你所说的)。如果您没有符合标准的编译器,那么它也可以做非标准的事情,比如销毁代码


<>大多数编译器都会公布它们遵循的C++标准的子集,所以你可以总是把代码写在那个特定的标准上,并且大多假设你是安全的。但是,如果没有在第一时间遇到编译器中的bug,您就无法真正防范它们,因此您仍然无法真正保证任何事情。

在声明访问易失性内存位置或IO设备时,如果没有包含volatile关键字,则是代码中的一个bug;即使只有当代码得到优化时,bug才明显

您的编译器将记录任何“不安全”的优化,其中它记录了打开和关闭它们的命令行开关和杂注。不安全的优化通常与浮点数学假设(舍入、像NAN这样的边缘情况)或其他人已经提到的别名有关

不断折叠会产生别名,使代码中出现错误。例如,如果您有如下代码:

static char *caBuffer = "                                         ";

...

strcpy(caBuffer,...)
您的代码基本上是一个在常量(文字)上涂鸦的错误。如果没有不断的折叠,错误将不会真正影响任何东西。但很像您提到的volatile bug,当编译器折叠常量以节省空间时,您可能会在另一个文本上涂鸦,如中的空格:

printf("%s%s%s",cpName,"   ",cpDescription);

因为编译器可能会将literal参数指向用于初始化caBuffer的literal的最后4个字符处的printf调用。

编译器优化导致的错误不是源于代码中的错误,是不可预测的,也很难确定(我在检查编译器在优化我的代码的某个区域时创建的汇编代码时,曾设法找到过一次)。常见的情况是,如果优化使程序不稳定,它只会暴露程序中的一个缺陷。

只要您的代码