Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.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++ 编译器中的优化范围是什么?_C++_Memory_Activex - Fatal编程技术网

C++ 编译器中的优化范围是什么?

C++ 编译器中的优化范围是什么?,c++,memory,activex,C++,Memory,Activex,当编译器优化代码时,优化的范围是什么?是否可以进行优化 a) 跨越多组嵌套大括号? b) 跨越多个功能? c) 跨越多个文件 我们正在追踪一个似乎源于优化的模糊bug。代码在发布模式下崩溃,但在调试模式下不崩溃。当然,我们知道这可能是堆损坏或其他内存问题,bur已经对此进行了一段时间的研究。我们正在考虑的一种方法是在调试模式下有选择地编译文件,直到问题消失。换言之: a) 从发布模式下编译的所有文件开始 b) 在调试模式下编译1/2文件 如果仍然可以看到崩溃,则取发行版编译文件的一半,并在调试模

当编译器优化代码时,优化的范围是什么?是否可以进行优化
a) 跨越多组嵌套大括号?
b) 跨越多个功能?
c) 跨越多个文件

我们正在追踪一个似乎源于优化的模糊bug。代码在发布模式下崩溃,但在调试模式下不崩溃。当然,我们知道这可能是堆损坏或其他内存问题,bur已经对此进行了一段时间的研究。我们正在考虑的一种方法是在调试模式下有选择地编译文件,直到问题消失。换言之:

a) 从发布模式下编译的所有文件开始
b) 在调试模式下编译1/2文件
如果仍然可以看到崩溃,则取发行版编译文件的一半,并在调试模式下编译
如果未看到崩溃,则谈论在调试模式下编译的一半文件,并在发布模式下编译
重复此操作,直到我们缩小可疑文件的范围
这是一个二进制搜索,用于缩小问题文件的范围

我们知道,如果这是一个内存问题,简单地进行这种混合编译可能会使bug消失,但如果我们能够缩小问题文件的范围,我们会感到非常紧张


然而,悬而未决的问题是优化的范围是什么——它们可以跨越多个文件吗

优化可以做任何事情,只要它不改变语言定义的行为语义。这意味着你的第一个问题(a)、(b)和(c)的答案都是肯定的。实际上,大多数编译器并没有那么雄心勃勃,但肯定有一些例子。Clang和LLVM具有允许优化几乎跨越整个程序的标志。MSVC有一个类似的标志,允许对整个程序进行优化

这类失败的原因通常是未初始化的变量。静态分析工具可以非常有助于发现您所描述的问题。我不确定通过优化进行的二进制搜索是否会帮助您跟踪太多内容,尽管这是可能的。您的bug可能是模块之间相当复杂的交互的结果


祝你好运

要了解编译器优化,一个简单的资源可能是wikipedia。它很好地简要地解释了几乎所有现代编译器所实现的一些重要的和广泛的优化

也许,您想先阅读wiki条目,尤其是以下部分:


您可以从发布模式下的崩溃调用跟踪中大致确定问题文件。然后尝试在不进行优化的情况下重建它们-这比二进制搜索简单得多。

我认为你问错了问题

优化器不太可能是您的问题(除非您正在做一些特殊的事情)

问题很可能是代码中未初始化的变量。
当您在调试模式下编译时,大多数编译器都会将所有内存初始化为特定模式,以便在调试过程中您可以看到内存发生了什么情况(是否已分配/是否已解除所有涂层/是否已从堆栈中取出/堆栈是否从等)

因此,在调试模式下,任何未初始化的内存都具有特定的模式,调试器可以识别该模式。确切的模式将取决于编译器。但这可能会使草率的代码工作,因为未初始化的指针为NULL,整数计数器从0开始,等等

当您为发布模式编译时,所有额外的初始化都将关闭。如果未显式初始化内存,它将处于随机状态。这就是应用程序调试/发布版本的不同行为

检查此问题的简单方法是检查编译器警告。

确保使用前所有变量都已初始化(它将出现在警告中)。

+1静态分析工具,在最高警告级别编译时没有任何警告,内存调试器都是我想到的工具。感谢您的建议,但我已经尝试了所有这些-内存工具,高警告级别等。这就是为什么我们开始怀疑一个优化错误。@Andrew-您使用了什么静态分析工具?我在Coverity的跨过程分析方面运气很好。@Andrew S:编译器错误是可能的,但相当罕见。看看你是否可以缩小问题的范围,然后再单独提出一个问题。根据我的经验,编译器的bug很少。非常非常非常非常非常可能代码中有一个真正的语义错误,而这个错误恰好是通过优化构建的结果才暴露出来的。下面是一个有趣的发布模式。您是否有任何非琐碎的断言?一个在过去让我头疼的警告:如果您的代码有许多由#ifdef#u DEBUG/#endif括起的部分,那么您在调试模式和发布模式下有不同的代码基础。首先比较在调试和发布模式下生成的预处理代码。错误可能是因为您没有初始化变量。在调试模式下,编译器将所有未初始化的变量设置为0(或类似值,具体取决于编译器)。在释放模式下,未初始化的变量是
未定义的
。打开警告(您将在那里看到),并确保所有变量在使用前都已初始化。注意:某些编译器不支持混合和调试二进制文件。从技术上更改任何输入标志都可能产生二进制不兼容。这就是为什么大多数编译器将release/debug编译到单独的目录中,这样它们就不能混合使用了。