我正在尝试重现示例代码,以便更好地理解C ++的 -if-if规则。根据{{3}}。
int& preinc(int& n) { return ++n; }
int add(int n, int m) { return n+m; }
// volatile input to prevent constant folding
volatile int input = 7;
// volatile output to make the result a visible side-effect
volatile int result;
int main()
{
int n = input;
// using built-in operators would invoke undefined behavior
// int m = ++n + ++n;
// but using functions makes sure the code executes as-if
// the functions were not overlapped
int m = add(preinc(n), preinc(n));
result = m;
}
我使用g++ -s main.cpp
从源代码获取汇编器输出,输出文件main()
的{{1}}函数如下所示:
main.s
根据输出文件,我认为即使我添加了main:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
pushq %rbx
subq $24, %rsp
.cfi_offset 3, -24
movq %fs:40, %rax
movq %rax, -24(%rbp)
xorl %eax, %eax
movl input(%rip), %eax
movl %eax, -32(%rbp)
leaq -32(%rbp), %rax
movq %rax, %rdi
call _Z6preincRi
movl (%rax), %ebx
leaq -32(%rbp), %rax
movq %rax, %rdi
call _Z6preincRi
movl (%rax), %eax
movl %ebx, %esi
movl %eax, %edi
call _Z3addii
movl %eax, -28(%rbp)
movl -28(%rbp), %eax
movl %eax, result(%rip)
movl $0, %eax
movq -24(%rbp), %rdx
xorq %fs:40, %rdx
je .L7
call __stack_chk_fail
编译选项,g ++编译器也只能逐句编译源代码而没有优化。
由于输出假设是这样的:
-O3
我想知道如何获得如下所示的汇编器输出代码。
答案 0 :(得分:0)
我测试示例代码时出了点问题。这是我提出的答案,总结了我的一些想法以及上面其他人的评论。
除非添加了“ -O3”或“ -O2”编译选项,否则编译器将优化代码。就像@BalázsKovacsics和@molbdnilo在评论中说的那样。使用命令g++ -S main.cpp
可以像问题中显示的那样逐句获取汇编器输出。
一旦添加了“ -O3”或“ -O2”编译选项,则意味着程序员允许编译器执行任何不会改变程序可观察行为的代码转换。因此,使用main()
main.s
的{{1}}功能
g++ -S -O3 main.cpp
请注意,编译器选项应以大写书写。
这里是compiler explorer网站@JulianH提供的,它非常方便地查看不同平台和不同编译器之间的汇编器输出。
我认为获取汇编程序输出有助于我更好地理解-如果规则。我希望我写的文章能对也对cppreference的抽象描述感到困惑的人有所帮助。