(本当に正当な理由なしに C プリプロセッサを悪用しないという標準的な免責事項がここに適用されます。)
やりたいことは必ず実現できます。STRINGIFY
マクロと少しのマクロ間接化が必要です。
通常、STRINGIFY
C プリプロセッサが引数を文字列化する前に展開できるように、1 レベルの間接化で定義されます。1 つの実装は次のとおりです。
/* The # operator converts symbol 'v' into a string */
#define STRINGIFY0(v) #v
#define STRINGIFY(v) STRINGIFY0(v)
ただし、これでは不十分であることがわかります。
#define _ACD 5, 5, 5, 30
#define DEFAULT_NETWORK_TOKEN_KEY_CLASS _ACD
#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS }
#define START_MSG STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS)
const char startMsg[] = START_MSG;
ここで は にSTRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS)
展開され、C プリプロセッサは引数が多すぎるSTRINGIFY0(5,5,5,30)
と文句を言います。STRINGIFY0
解決策は、展開を遅らせて、必要なとき_ACD
にのみ展開する5,5,5,30
ことです。これを行うには、関数のようなマクロとして定義します。
#define _ACD() 5, 5, 5, 30
このように、_ACD
「呼び出す」ときにのみ展開されます: _ACD()
. DEFAULT_NETWORK_TOKEN_KEY_CLASS
は に展開され_ACD
、それを「呼び出す」ことでさらに展開する必要があります: DEFAULT_NETWORK_TOKEN_KEY_CLASS()
。
次のコードは、ソリューションを示しています。
#include <stdio.h>
#define STRINGIFY0(v) #v
#define STRINGIFY(v) STRINGIFY0(v)
#define _ACD() 5, 5, 5, 30
#define DEFAULT_NETWORK_TOKEN_KEY_CLASS _ACD
#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS() }
#define START_MSG STRINGIFY(DEFAULT_NETWORK_TOKEN_KEY_CLASS)
const char startMsg[] = START_MSG;
int main(int argc, char** argv)
{
printf("%s\n",startMsg);
return 0;
}