我正在用 C++/Qt 编写一个程序,其中包含图形文件解析器。我用g++
编译项目。
在开发过程中,我不断比较有关优化和调试信息的不同编译器标志之间的低级解析器层的性能,以及 Qt 的调试标志(打开/关闭 qDebug() 和 Q_ASSERT())。
现在我面临一个问题唯一正常运行的构建是没有任何优化的构建。所有其他版本,即使有-O1
,似乎以另一种方式工作。它们由于不满足的断言而崩溃,而在没有-O...
旗帜。该代码不会产生任何编译器警告,即使使用-Wall
.
我非常确定我的程序中存在错误,这似乎只有在启用优化时才会有害。问题是:即使调试程序也找不到它。解析器似乎从文件中读取了错误的数据。当我运行一些简单的测试用例时,它们运行得很好。当我运行更大的测试用例(直接从文件读取的图形上的路线计算)时,文件中存在我无法解释的错误读取。
我应该从哪里开始追踪这种未定义行为的问题?这种不同的行为可能涉及哪些优化方法?(我可以一个接一个地启用所有标志,但我不知道那么多编译器标志,但是-O...
而且我知道它们有很多,所以这需要很长的时间。)一旦我知道 bug 属于哪种类型,我确信我迟早会找到它。
如果您能告诉我哪些编译器优化方法可能适合此类问题,那么您可以为我提供很多帮助。
有几类错误通常在优化构建中出现,而在调试构建中通常不会出现。
未初始化的变量。编译器可以捕获一些但不是全部。查看所有构造函数,查看全局变量。等等。特别是寻找未初始化的指针。在调试版本中,内存重置为零,但在发布版本中则不然。
使用超出范围的临时对象。例如,当您返回对函数中的本地临时对象的引用时。这些通常在调试版本中起作用,因为堆栈被填充得更多。临时对象往往会在堆栈上存活更长时间。
数组超出了临时数据的写入范围。例如,如果您在函数中创建一个数组作为临时数组,然后在末尾写入一个元素。同样,堆栈将在调试中拥有额外的空间(用于调试信息),并且溢出不会影响程序数据。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)