【发布时间】:2021-07-24 02:26:59
【问题描述】:
我有以下要调试的示例程序:
#include <iostream>
#include <assert.h>
using namespace std;
int f(int x) {
assert(false); // something bad happens
return 2 * x;
}
int main() {
int a;
for (int i = 0; i < 5; i++) {
a++; // a is uninitialized
cout << a << endl;
}
cout << f(1) << endl;
}
这段代码有两个问题:
- 循环内的变量
a未初始化 - 函数
f导致程序崩溃
为了检测这些问题,我使用g++ -Wall -Og -g source.cpp 进行编译,并收到以下警告:
source.cpp: In function ‘int main()’:
source.cpp:17:10: warning: ‘a’ may be used uninitialized in this function [-Wmaybe-uninitialized]
17 | a++; // a is uninitialized
|
正如this 问题所示,-Og 标志(或任何其他优化标志)对于获取此警告是必要的。
当我使用 gdb 调试生成的可执行文件时,它会崩溃(因为 assert 语句)并且回溯看起来像这样:
[...]
#4 0x000055555555528f in f (x=<optimized out>) at source.cpp:7
#5 0x0000555555555322 in main () at source.cpp:21
如您所见,变量x 已被优化。发生这种情况是因为 -Og 标志,如 this 问题中所述。
显然,我不希望将其用于调试目的。但是当我删除-Og 标志时,前面提到的警告将不再出现。我现在想找到一种方法来获得此警告,而无需优化变量。 g++ 可以做到这一点吗?
我在 Ubuntu 20.10 上使用 g++ 版本 10.2.0 和 gdb 版本 9.2。
【问题讨论】:
-
嗯,我不使用
-Oghere,但我仍然收到警告。 -
@NathanOliver 是的,我搞砸了,使用了错误的代码。我编辑了我的帖子。现在它应该是正确的。
-
因为检测未初始化的变量需要做程序流分析(查看从声明到第一次使用的每一个可能的代码路径),这很昂贵。许多编译器将此检测推迟到优化阶段,出于优化原因,无论如何都会进行此类分析。
-
@largest_prime_is_463035818 这看起来很有趣。
-Wuninitialized=verbose标志会非常有用。
标签: c++ gdb g++ gcc-warning compiler-flags