これはインタビューの質問に少し似ていますが、実際には実際的な問題です。
私は組み込みプラットフォームで作業しており、それらの機能に相当するもののみを利用できます。
さらに、printf()実装(および署名)は近い将来変更される可能性が高いため、後で移行しやすくするために、別のモジュールに呼び出す必要があります。
それらを考慮して、ロギング呼び出しをいくつかの関数またはマクロでラップできますか?目標は、私のソースコードがTHAT_MACRO("Number of bunnies: %d", numBunnies);
を1000箇所で呼び出すことですが、上記の関数の呼び出しは1箇所でしか見られません。
コンパイラ:arm-gcc -std = c99
C99を使用できるため、 variadic macro でラップします。
#define TM_PRINTF(f_, ...) printf((f_), __VA_ARGS__)
#define TM_SNPRINTF(s_, sz_, f_, ...) snprintf((s_), (sz_), (f_), __VA_ARGS__)
vprintf
またはそれに類するものがあるとは言わなかったからです。そのようなものがある場合は、Sergey Lが彼の答えで提供したような関数でラップすることができます。
上記のTM_PRINTFは、空のVA_ARGSリストでは機能しません。少なくともGCCでは、次のように記述できます。
#define TM_PRINTF(f_, ...) printf((f_), ##__VA_ARGS__)
2つの##記号は、__VA_ARGS__
が空の場合、それらの前にある余分なコンマを削除します。
これを行うには2つの方法があります。
Variadricマクロ
#define my_printf(...) printf(__VA_ARGS__)
va_args
を転送する関数
#include <stdarg.h>
#include <stdio.h>
void my_printf(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
vsnprintf
、vfprintf
、およびstdio
で考えられるものもあります。
呼び出しをtwo括弧で囲む必要がある場合は、次のようにできます。
#define THAT_MACRO(pargs) printf pargs
次にそれを使用します:
THAT_MACRO(("This is a string: %s\n", "foo"));
^
|
OMG
これは、プリプロセッサの観点から、引数のリスト全体が1つのマクロ引数になり、括弧で置き換えられるため、機能します。
これは単純なことよりも優れています
#define THAT_MACRO printf
それを定義することができるので:
#define THAT_MACRO(pargs) /* nothing */
これはマクロ引数を「使い果たし」、コンパイルされたコードの一部になることはありません。
[〜#〜] update [〜#〜]もちろん、C99ではこの手法は廃止されており、変数マクロを使用して満足しているだけです。
_#define TM_PRINTF(f_, ...) printf((f_), ##__VA_ARGS__)
_
_##
_トークンは、使用法TM_PRINTF("aaa");
を有効にします
_#define PRINTF(...) printf(__VA_ARGS__)
_
これは次のように機能します。
パラメーター化されたマクロPRINTFを定義して(最大)無限の引数を受け入れ、PRINTF(...)
からprintf(__VA_ARGS__)
に前処理します。 ___VA_ARGS__
_は、指定された引数を示すためにパラメーター化されたマクロ定義で使用されます(無限引数に名前を付けることはできないのですか?)。
限られた図書館?組み込みシステム?できるだけ多くのパフォーマンスが必要ですか?問題ない!
この質問 に対するこの回答で示されているように、アセンブリ言語を使用して、VA_LISTを受け入れない関数をラップし、わずかなコストで独自のvprintfを実装できます!
これは機能しますが、ほぼ確実に必要なパフォーマンスと抽象化をもたらしますが、おそらく Clibc の一部をスライスすることで、より多くの機能を備えた標準ライブラリを取得することをお勧めします。このようなソリューションは、すべてのサイクルを絶対に必要としない限り、アセンブリを使用するよりも、より移植性があり、全体的に有用な答えになるはずです。
結局、そのようなプロジェクトが存在する理由です。