他の回答に加えて、GCC での printf 形式のチェックに関する詳細情報を次に示します。
あなたが言うとき__attribute__((__format__ (FORMAT, ...)))
、の値はFORMAT
(printfに関する限り)次のいずれかです:printf
、、。gnu_printf
ms_printf
ms_printf
関数が Microsoft Visual Studio CRT の printf ファミリ関数用の書式文字列を受け取ると GCC に想定させます。z
これは、GCC が、hh
およびについて不平を言うことを意味しますが、警告なしll
に通過します。I64
gnu_printf
GCC は、その下に GNU libc printf 実装を想定します (または、POSIX/C99 準拠の printf 実装だけかもしれませんが、よくわかりません)。したがって、GCC は およびその他の Microsoft 拡張機能について不平を言いますが、 、およびI64
を受け入れます。z
hh
ll
printf
は、ms_printf
Windows 用にコンパイルする場合のエイリアスであり、gnu_printf
それ以外の場合のエイリアスです。
このチェックは、使用されている実際の printf 実装と完全に直交していることに注意してください。これは、独自の printf のような関数を作成して配置すると簡単に確認できます。GCC__attribute__((__format__ (FORMAT, ...)))
は に応じてさまざまなことについて文句を言いFORMAT
ますが、関数内でやりたいことは何でもできます。
私が知っている利用可能なprintf実装:
-D__USE_MINGW_ANSI_STDIO=1
MinGW.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 は最悪のケースを想定しているようです)。z
hh
- gnulib。完全に(またはほぼ完全に)準拠してい
ms_printf
ます。gnu_printf
MinGW.orgのstdio.h
ヘッダーは を使用しませんattribute format
。
stdio.h
MinGW-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
ます