私はこれに対する答えを数日間探していましたが、思いついたすべての結果は、printfが任意の数の引数を受け入れる方法に関するものです。
Printfはstdoutにどのように書き込みますか? Cでファイルに書き込む最も基本的な方法は何ですか?標準ライブラリはどのように機能しますか?
一部のオペレーティングシステムで実行されているユーザープログラムからの最低レベル、libcは システムコール (またはsyscalls)を作成しています。これらは多くの場合、いくつかのパラメーターが指定され、 マイクロプロセッサー を スーパーバイザーモード に切り替える単一の機械命令(多くの場合SYSCALL
またはSYSENTER
)です。制御された方法で。次に kernel はパラメーターを処理し、syscallを処理して、最終的にユーザー空間に戻ります。 Linuxの場合は、その Assembly HowTo および x86-64 ABI 仕様を参照してください。
ところで、Linuxをインストールして、いくつかのlibcのソースコードを調べることができます。 musl-libc は非常に読みやすいことに注意してください。
もちろん、syscalls(およびそれらを呼び出すプロトコル)はオペレーティングシステム固有です。 syscalls(2) を読んで、それらのリストを取得できます(Linuxの場合)。
printf
(およびputs
)は、最終的に write(2) syscallを呼び出します。パフォーマンス上の理由から、<stdio.h>
はバッファリングしています。
printf
は C99 (プログラミング言語標準)で標準化されていますが、write
は [〜#〜] posix [〜#〜 ]ポータブルオペレーティングシステムインターフェイス標準(ただし、Microsoft WindowsはPOSIXに準拠していません)。
多くの場合、printf
はfputs
を呼び出さず、syscallを使用します(Linuxのwrite
など)。ところで、一部の実装(特に [〜#〜] gcc [〜#〜] コンパイラと GNU libc は、__builtin__snprintf*
に含まれる/usr/include/bits/stdio2.h
に組み込まれている<stdio.h>
ビルトインを介して) printf
へのいくつかの単純な呼び出しをputs
....への呼び出しに最適化します。
printf( string, ... )
は(* 1)内部で呼び出すvfprintf( stdout, string, va_list )
と見なすことができ、これは内部でfputs( string, stdout )
を呼び出すと見なすことができます
fputs( string, stdout )
の実装は、オペレーティングシステム固有です。
したがって、標準ライブラリ(の一部)はオペレーティングシステムごとに書き直され、その目的を達成するために、基盤となるシステムによって提供されるネイティブ機能を利用します。
(* 1)私は「考えられる」と言います。正確にそれを行うのか、それと同等の何かを行うのかは実装固有であり、私たちの関心事ではないためです。