2016-10-18 44 views
1

「printfのは」本当に印刷された文字の数を返しますので、私は持っていた:

#include<stdio.h> 
int main() 
{ 
    printf("1"); 
    printf("55555"); 
    printf("10________"); 
    printf("13___________"); 
    printf("18________________"); 
    printf("28__________________________"); 
} 

このプログラムは出力

15555510________13___________18________________28__________________________ 

それから私は、GDBでそれをデバッグし、GDBの戻り値をチェックしようとしただろう:

(gdb) b main 
Breakpoint 1 at 0x804844c: file testp.c, line 4. 
(gdb) r 
Starting program: /home/a/cpp/a.out 

Breakpoint 1, main() at testp.c:4 
4  printf("1"); 
(gdb) n    # will return "1" to $eax 
5  printf("55555"); 
(gdb) p $eax   # I expect it will print "1" here, wrong! 
$1 = 49 
(gdb) n 
6  printf("10________"); 
(gdb) p $eax   # I expect it will print "5" here, right! 
$2 = 5 
(gdb) n 
7  printf("13____________"); 
(gdb) p $eax   # I expect it will print "10" here, right! 
$3 = 10 

最初のprintfが実行されたときにわかるように、$ eax値は私の期待通りではありません。後の値は正しいと思われる。 これはなぜですか?なぜ最初にprintfが "1"を$ eaxに返さないのですか?私はCスタイルのABIが$ eaxに戻り値を格納すると思います。

答えて

1

GCCは、このような最適化は、(例えば、機能の文書化動作を変更しないであろう特定の場合においてputs又はputcharの呼び出しなど、より効率的なコードでprintfの呼び出しを置き換えることができ

おかげ出力には書式設定が必要なく、戻り値は使用しません)。それがここで起こっていることです。 putcharは、出力された文字、またはEOFを返すので、%eaxで49が表示されています。

(gdb) disass /m main 
Dump of assembler code for function main: 
3 { 
    0x000000000040057d <+0>: push %rbp 
    0x000000000040057e <+1>: mov %rsp,%rbp 

4  printf("1"); 
    0x0000000000400581 <+4>: mov $0x31,%edi 
    0x0000000000400586 <+9>: callq 0x400450 <[email protected]> 

5  printf("55555"); 
    0x000000000040058b <+14>: mov $0x400664,%edi 
    0x0000000000400590 <+19>: mov $0x0,%eax 
    0x0000000000400595 <+24>: callq 0x400460 <[email protected]> 

はgccがprintfへの呼び出しを生成するために、すべての時間を取得するには、-fno-builtin-printfオプションを使用することができます。

+0

ありがとうございます。-fno-builtin-printfは私の仕事です。私はちょうど混乱していました、私は "-O"オプションを使用しなかった、または最適化を行いました、なぜgccはまだいくつかの最適化をしていますか?手動で完全に無効にするには? – Troskyvs

+0

'-O0'を指定しても、' -fno-builtin'または 'no-builtin-nameoffunc'オプションを指定しない限り、gccは' printf'や 'strcpy'のような標準関数の代わりに同等の効率的なコードを使います。 –

関連する問題