c++ - 如何消除仅在启用优化时出现的错误

标签 c++ linux gcc

我有点陷入困境。我有一些代码直到最近运行良好,但现在在启用优化时开始失败。此代码在禁用优化 -O0 的情况下运行良好,-O1-O2 都会导致问题发生(我不使用 -O3)。

不幸的是,我无法发布源代码(它相当复杂且专有),但我将尝试一个最小的工作示例。同时,我很想听听任何有经验的人的意见,在启用优化的情况下,C++ 的方式甚至能够导致意外的结果(有什么陷阱?我应该首先检查什么?)。

这里至少可以让您大致了解我第一次发现问题的代码:

struct Slice {
  const char* m_Data;
  size_t m_Size;
}
char scratch[1024];
Slice result;
Read(read, &result, scratch);
// with optimizations disabled, result contains 40 bytes of data with optimizations enabled m_Size is suddenly zero!?

这确实没什么花哨的,这是简单明了的C++

我使用的是 gcc-4.8.1,但在 OS X 上使用 clang++ 时也遇到同样的问题(Windows 上的 Visual C++ 似乎没有这个问题)。

最佳答案

通常这种不稳定的行为(不同优化选项的不同结果,或者不同编译器下的不同结果,甚至不同运行的不同结果)是由于未定义的行为而发生的,并且最常见的是由于一些内存管理问题(未初始化的值使用,错误的指针管理等)

有一些特殊的工具可以识别一些(尽管不是全部)此类问题。

其中之一是valgrind,您只需构建程序并调用valgrind ./program。它将跟踪许多内存访问问题、未初始化的值等。尽管它会大大降低性能。

另一个是编译器的地址清理选项。对于 gcc,您可以使用 -fsanitize=address 构建程序,然后正常运行程序。对于其他编译器可能有类似的选项。它捕获的问题与 valgrind 略有不同,并且没有太多性能问题。

在这两种情况下,您都可以使用任何优化选项来构建程序。无论如何,问题很可能会出现。可能会出现一些误报,但这可能取决于您的代码。

另一组工具是静态代码分析器,例如 cppcheck。

当然,像往常一样,您可以尝试调试程序或添加调试输出等,但这可能不是那么有效,因为对程序的任何更改都可以使行为恢复正常。

关于c++ - 如何消除仅在启用优化时出现的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29945886/

相关文章:

c++ - 将 Qt DLL 保存在单独的文件夹中

c++ - 使用 short 和 long 而不是 int 和 double (C++)

python - Linux 命令行调用没有从 os.system 返回它应该返回的内容?

gcc - 在cygwin下使用GCC生成的可执行文件

c++ - 将 C++ 从 Linux 移植到 Windows, '__aligned__'

c - 在运行时替换动态共享库

javascript - Ruby on Rails Partial 不会使用 AJAX 刷新,但表示它正在控制台中呈现部分

c++ - 如何使用 `--wrap` 选项正确包装函数?

linux - 在 Linux-PowerPC 上使用 GCC 连接到 DB2/400

c++ - 在 C++ 中正确使用/包含 uint64_t