static inline __printf(2, 3)
int dev_err(const struct device *dev, const char *fmt, ...)
{ return 0; }
__printf()
dev_err の 3 番目の引数 (...) は何をしていて、何を意味していますか? この関数がある種の汎用関数であることを視覚化できます。それは何をするためのものか?
static inline __printf(2, 3)
int dev_err(const struct device *dev, const char *fmt, ...)
{ return 0; }
__printf()
dev_err の 3 番目の引数 (...) は何をしていて、何を意味していますか? この関数がある種の汎用関数であることを視覚化できます。それは何をするためのものか?
.を除いて、ほとんどすべて標準 (可変引数処理)__printf(2,3)
です。
関数に対するこの修飾子 ( static
or修飾子と同様) は、スタイル形式指定子を使用して、引数 3 で始まる実際のパラメーターに対して、inline
引数 2 の形式文字列 ( ) をチェックする必要があることをコンパイラに伝えます。fmt
printf
つまり、次のように呼び出します。
dev_err (pDev, "%d", 1.0);
書式文字列と実際の引数が一致しないため、警告が表示されます。
は、それ自体の実装...
方法と同様に、フォーマット文字列の後に可変数の引数があることを単に示しています。printf
C には長い間、変数の引数リストを処理する機能がありました。__printf()
修飾子は、関数の使用を検証できるように、コンパイラに少し追加の情報を与えるだけです。
Linux では__printf(a, b)
asが定義されて__attribute__((format(printf, a, b)))
おり、gcc では 2 番目の形式で varargs-checking 属性を次のように指定できます(以下に言い換え):
形式 (アーキタイプ、文字列インデックス、最初にチェックする):
format 属性は、関数が printf、scanf、strftime、または strfmon スタイルの引数を取ることを指定します。これらの引数は、フォーマット文字列に対して型チェックする必要があります。たとえば、宣言は次のとおりです。
extern int my_printf (void *my_object, const char *my_format, ...)
__attribute__ ((format (printf, 2, 3)));
コンパイラは、my_printf への呼び出しの引数をチェックして、printf スタイルの書式文字列引数 my_format との一貫性を確認します。
上記の例では、フォーマット文字列 (my_format) は関数 my_print の 2 番目の引数であり、チェックする引数は 3 番目の引数から始まるため、format 属性の正しいパラメーターは 2 と 3 です。
format 属性を使用すると、フォーマット文字列を引数として取る独自の関数を識別できるため、GCC はこれらの関数の呼び出しでエラーをチェックできます。
関数自体が何をするかについては、ゼロを返すこと以外にはあまりありません:-)
dev_err()
実際の関数を実際に実装したい場合は、ほぼ間違いなくプレースホルダーです。