相关疑难解决方法(0)

为什么clang用-O0生成效率低的asm(对于这个简单的浮点和)?

我在llvm clang Apple LLVM 8.0.0版(clang-800.0.42.1)上反汇编代码:

int main() {
    float a=0.151234;
    float b=0.2;
    float c=a+b;
    printf("%f", c);
}
Run Code Online (Sandbox Code Playgroud)

我编译时没有-O规范,但我也试过-O0(给出相同)和-O2(实际上计算值并存储它预先计算)

产生的反汇编如下(我删除了不相关的部分)

->  0x100000f30 <+0>:  pushq  %rbp
    0x100000f31 <+1>:  movq   %rsp, %rbp
    0x100000f34 <+4>:  subq   $0x10, %rsp
    0x100000f38 <+8>:  leaq   0x6d(%rip), %rdi       
    0x100000f3f <+15>: movss  0x5d(%rip), %xmm0           
    0x100000f47 <+23>: movss  0x59(%rip), %xmm1        
    0x100000f4f <+31>: movss  %xmm1, -0x4(%rbp)  
    0x100000f54 <+36>: movss  %xmm0, -0x8(%rbp)
    0x100000f59 <+41>: movss  -0x4(%rbp), %xmm0         
    0x100000f5e <+46>: addss  -0x8(%rbp), %xmm0
    0x100000f63 <+51>: movss  %xmm0, -0xc(%rbp)
    ...
Run Code Online (Sandbox Code Playgroud)

显然它正在做以下事情:

  1. 将两个浮点数加载到寄存器xmm0和xmm1上
  2. 把它们放在堆栈中
  3. 从堆栈加载一个值(不是之前的xmm0)到xmm0
  4. 执行添加. …

c assembly x86-64 compiler-optimization llvm-codegen

4
推荐指数
1
解决办法
333
查看次数

当脱离非 void 函数末尾时写入未使用的参数的返回值

在这个高尔夫答案中,我看到了一个技巧,其中返回值是未传入的第二个参数。

int f(i, j) 
{
    j = i;   
}

int main() 
{
    return f(3);
}
Run Code Online (Sandbox Code Playgroud)

gcc 的汇编输出来看,当代码复制时,j = i它存储的结果eax恰好是返回值。

f:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    %edi, -4(%rbp)
        movl    %esi, -8(%rbp)
        movl    -4(%rbp), %eax
        movl    %eax, -8(%rbp)
        nop
        popq    %rbp
        ret
main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $3, %edi
        movl    $0, %eax
        call    f
        popq    %rbp
        ret 
Run Code Online (Sandbox Code Playgroud)

那么,这一切仅仅是因为幸运吗?gcc 对此有记录吗?它只适用于,但它适用于我尝试过-O0的一堆值,以及一堆不同版本的 GCC。i-m32

c x86 gcc return-value kernighan-and-ritchie

3
推荐指数
1
解决办法
440
查看次数

检查函数的返回值而不返回return语句

使用下面的例子,请解释为什么有时候不需要return语句?函数具有返回类型,但缺少return语句.同时,程序编译和工作正常.

请帮助我更好地理解这一点

char* handleInput() {
    fgets(buffer, 1024, stdin);
**//    return buffer;**       <---- COMMENTED RETURN
}

void main() {
        char* ptr = handleInput();
        int flag = atoi(ptr);    
        if (flag < 0) break;    
        printf("You entered: %s\n", ptr);
}
Run Code Online (Sandbox Code Playgroud)

c return-value

2
推荐指数
2
解决办法
1662
查看次数