9

別の質問に答える一環として、gcc-O3)の非常識なレベルの最適化により、mainで使用されなかった変数が基本的に削除されることを示したいと思いました。コードは次のとおりです。

#include <stdio.h>
int main (void) {
   char bing[71];
   int x = 7;
   bing[0] = 11;
   return 0;
}

gcc -O3出力は次のとおりです。

    .file "qq.c"
    .text
    .p2align 4,,15
.globl main
    .type main, @function
main:
    pushl %ebp
    xorl %eax, %eax
    movl %esp, %ebp
    popl %ebp
    ret
    .size main, .-main
    .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section .note.GNU-stack,"",@progbits

これで、ローカル変数が削除されたことがわかりますが、まだかなりの無駄があります。私には、全体が次のように思われます。

    pushl %ebp
    xorl %eax, %eax
    movl %esp, %ebp
    popl %ebp
    ret

セクションは、より単純なものに置き換えることができます。

    xorl %eax, %eax
    ret

なぜgccこの最適化を実行しないのか、誰かが知っていますか?それ自体はほとんど節約できないことはわかっていmainますが、これが通常の関数でも行われた場合、大規模なループでスタックポインタを不必要に調整することによる影響はかなり大きくなります。

アセンブリの生成に使用されたコマンドは次のとおりです。

gcc -O3 -std=c99 -S qq.c
4

2 に答える 2

9

-fomit-frame-pointerその特定の最適化は、コンパイラフラグを使用して有効にできます。これを行うと、一部のマシンではデバッグが不可能になり、他のすべてのマシンではデバッグが大幅に困難になります。そのため、通常は無効になっています。

GCCのドキュメントには-fomit-frame-pointer、さまざまな最適化レベルで有効になっていると記載されている場合がありますが、そうではない場合があります。ほぼ確実に、自分で明示的に有効にする必要があります。

于 2011-02-23T02:14:25.043 に答える
6

-fomit-frame-pointersource )をオンにすると、余分なスタック操作がなくなります。

-fomit-frame-pointerGCC 4.6以降のデフォルトはドキュメントに記載されていますが、GCCはデバッグ(必要に応じてスタックトレースを取得)を容易にするため、これらを残したようです。

于 2011-02-23T02:14:00.973 に答える