上周我调试了一个代码,出现了一个奇怪的情况:gdb传递了两个不同的return子句.我做了一个简单的例子说明了这种情况:
#include <iostream>
using namespace std;
int test() {
string a = "asd";
string b = "asd";
while (true) {
if (a == b) {
return 0;
}
}
return -1;
}
int main() {
int result = test();
cout << "result: " << result << endl;
}
Run Code Online (Sandbox Code Playgroud)
在调试我得到的代码时:
(gdb) b main
Breakpoint 1 at 0x1d4c: file example.cpp, line 19.
(gdb) r
Starting program: /Users/yuppienet/temp/a.out
Reading symbols for shared libraries +++. done
Breakpoint 1, main () at example.cpp:19
19 int result = test();
(gdb) s
test () at example.cpp:7
7 string a = "asd";
(gdb) n
8 string b = "asd";
(gdb) n
11 if (a == b) {
(gdb) n
12 return 0;
(gdb) n
15 return -1;
(gdb) n
16 }
(gdb) n
main () at example.cpp:20
20 cout << "result: " << result << endl;
(gdb) n
result: 0
21 }
(gdb) n
0x00001ab2 in start ()
Run Code Online (Sandbox Code Playgroud)
我注意到即使gdb显示第15行,返回值也是0(finish命令也确认了这一点).
所以问题是:为什么gdb显示第15行:return -1,即使函数没有真正返回这个值?
谢谢!
编辑:我忘了提到我用以下行编译:
g++ -Wall -pedantic -g -pg example.cpp
Run Code Online (Sandbox Code Playgroud)
我怀疑您正在看到函数尾声。您的两个字符串都有析构函数,它们在返回时被隐式调用。查看反汇编内容以确保确定,但我怀疑这两个 return 语句都映射到以下内容:
stash return_value;
goto epilogue;
Run Code Online (Sandbox Code Playgroud)
并相应地:
epilogue:
destroy a; // on the stack, so destructor will be called
destroy b;
really_return(stashed value);
Run Code Online (Sandbox Code Playgroud)
尾声似乎来自第 15 行,是 g++ 如何进行行编号的副作用 - 一种相当简单的格式,实际上只是“地址 X 来自行号 Y”形式的标签列表 - 因此它将 15 报告为最接近的匹配。在这种情况下令人困惑,但很多时候都是正确的。