他の回答に加えて、GCC での printf 形式のチェックに関する詳細情報を次に示します。
あなたが言うとき__attribute__((__format__ (FORMAT, ...)))、の値はFORMAT(printfに関する限り)次のいずれかです:printf、、。gnu_printfms_printf
ms_printf関数が Microsoft Visual Studio CRT の printf ファミリ関数用の書式文字列を受け取ると GCC に想定させます。zこれは、GCC が、hhおよびについて不平を言うことを意味しますが、警告なしllに通過します。I64
gnu_printfGCC は、その下に GNU libc printf 実装を想定します (または、POSIX/C99 準拠の printf 実装だけかもしれませんが、よくわかりません)。したがって、GCC は およびその他の Microsoft 拡張機能について不平を言いますが、 、およびI64を受け入れます。zhhll
printfは、ms_printfWindows 用にコンパイルする場合のエイリアスであり、gnu_printfそれ以外の場合のエイリアスです。
このチェックは、使用されている実際の printf 実装と完全に直交していることに注意してください。これは、独自の printf のような関数を作成して配置すると簡単に確認できます。GCC__attribute__((__format__ (FORMAT, ...)))は に応じてさまざまなことについて文句を言いFORMATますが、関数内でやりたいことは何でもできます。
私が知っている利用可能なprintf実装:
-D__USE_MINGW_ANSI_STDIO=1MinGW.org および MinGW-w64 ツールチェーンのMinGW ANSI STDIO (でコンパイル)。ms_printf(完全に?) および形式に準拠しgnu_printfます (部分的に - 位置引数をサポートしません)。
- MSVCRT (なしでコンパイル
-D__USE_MINGW_ANSI_STDIO=1)。準拠ms_printf(duh...)、準拠gnu_printfは非常に低く、ランタイム バージョンに依存します (古いバージョンはサポートしていませんでしたが、新しいバージョンはサポートしllています。これまでのところ、どのバージョンでもサポートされていません。ただし、GCC はこれらの開発を喜んで認識していません。 VC 6.0 時代の msvcrt は最悪のケースを想定しているようです)。zhh
- gnulib。完全に(またはほぼ完全に)準拠してい
ms_printfます。gnu_printf
MinGW.orgのstdio.hヘッダーは を使用しませんattribute format。
stdio.hMinGW-w64のヘッダーはattribute format gnu_printf、MinGW ANSI STDIO 実装に使用しますが、MSVCRT 実装には何も使用しません。修正済み: MinGW-w64 ヘッダーの新しいバージョンでは、MSVCRT 実装stdio.hに使用されます。attribute format ms_printf
gnulib は と の違いを完全に認識しておりprintf、gnu_printfいくつかの複雑なマクロに応じてどちらか一方を選択します (おそらく、フォーマットが示すことをサポートする適切な実装が付随しています)。
(現時点で) GCC フォーマット チェックに問題があることがわかっているソフトウェアの一部:
- glib -
printfフォーマットを使用しますが、実装は gnulib からです。に変更するための未解決のバグがありますgnu_printf
- CPython - コードにはさまざまな
z形式がありますが、公式のバイナリは MSVCRT に対してビルドされています。printf拡張機能もよく使用しますが、拡張ヘッダーにもフォーマットを使用しzます