有这个代码:
void func1()
{
std::cout << "func1" << std::endl;
}
void func2()
{
std::cout << "func2" << std::endl;
}
bool func3()
{
std::cout << "func3" << std::endl;
func1();
func2();
}
int main(int argc, char* argv[])
{
func3();
return 0;
}
正如你在函数中看到的,bool func3()错误是:函数没有返回值。如果你编译这个程序:
g++ -O2 main.cpp
然后我们得到以下行为
func3
func1
func2
func3
func1
func2
Ошибка сегментирования (стек памяти сброшен на диск)
问题:发生了什么?为什么函数被调用func3两次?以及为什么会出现分段错误,据我了解,只有在内存处理不正确时才会出现这样的错误。
在汇编程序中它看起来像这样(为简洁起见,我将输出删除到流中,行为被保留):
.file "main.cpp"
.text
.p2align 4
.globl _Z5func1v
.type _Z5func1v, @function
_Z5func1v:
.LFB0:
.cfi_startproc
endbr64
ret
.cfi_endproc
.LFE0:
.size _Z5func1v, .-_Z5func1v
.p2align 4
.globl _Z5func2v
.type _Z5func2v, @function
_Z5func2v:
.LFB5:
.cfi_startproc
endbr64
ret
.cfi_endproc
.LFE5:
.size _Z5func2v, .-_Z5func2v
.section .text.unlikely,"ax",@progbits
.globl _Z5func3v
.type _Z5func3v, @function
_Z5func3:
.LFB2:
.cfi_startproc
endbr64
.cfi_endproc
.LFE2:
.size _Z5func3v, .-_Z5func3v
.globl main
.type main, @function
main:
.LFB3:
.cfi_startproc
endbr64
.cfi_endproc
.LFE3:
.size main, .-main
.ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0"
.section .note.GNU-stack,"",@progbits
.section .note.gnu.property,"a"
.align 8
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 8
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 8
4:
有趣的是,如果您在没有优化的情况下进行编译,那么程序将正常工作。
g++ --version
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
看了汇编代码。没有团队
ret。并且该函数继续执行该函数main。Godbolt中没有循环。https://godbolt.org/z/ojnWP8