重现cppreference的按规则显示的示例代码

时间:2019-07-02 12:17:28

标签: c++ compiler-optimization

我正在尝试重现示例代码,以便更好地理解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

我想知道如何获得如下所示的汇编器输出代码。

1 个答案:

答案 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的抽象描述感到困惑的人有所帮助。

相关问题