2016-07-08 11 views
3

私の理解に基づいて、ltraceユーティリティを使用してライブラリ呼び出しをトレースします。 printfだけを呼び出す単純なプログラムがありますが、表示されるライブラリ関数はprintfの代わりにputsです。私はなぜそれがprintfしかし、putsを表示しないのが不思議ですか?ltrace printf()ですが、puts()を表示します

答えて

5

ltraceは、バイナリファイルで動作し、putsを呼び出すため、putsが呼び出されていることを示しています。

Example:ソース:

#include <stdio.h> 

int main(int c, char *v[]) 
{ 
    printf("hello world\n"); 
} 

は、アセンブリ:

.LC0: 
     .string "hello world" 
main: 
     subq $8, %rsp 
     movl $.LC0, %edi 
     call puts 
     xorl %eax, %eax 
     addq $8, %rsp 
     ret 

あなたはより多くの例でプレイする場合は、コンパイラは、ソースコードがないときmemcpyを呼び出すアセンブリ・コードを生成することを見つけることができ、ソースコードではmemcpy(または他の多くの共通関数の1つ)を呼び出さないアセンブリコードなどがあります。コンパイラはプログラムの意味を尊重する必要があるだけで、呼び出される実際の関数を尊重する必要はありません。 printfputsは、再定義することができない標準的な関数なので、これらの関数が何をしているかを知っており、有用であると考えられる場合には置き換えることができます。ここで

putsは(それが%フォーマットを解釈することはありませんし、それが可変長ではありません)単純であるため、より高速なので、putsprintfに置換しました。この場合、printfputsと置き換えることができました。文字列の印刷には書式指定子の解釈が必要なく、文字列の末尾が\nだったためです。

+0

ご返信ありがとうございます。 printfとputsの関係は何ですか? – HuangJie

+0

@HuangJie 'puts'は、'% '形式の指示を解釈しないので、より簡単です(したがって高速です)。そして、それ自身の最後に '\ n'を追加します。 –

1

単なる最適化です。コンパイラはprintf("smth\n")puts("smth")に置き換えます。出力は同じですが、puts()はより速く動作するはずです。

関連する問題