8

興味がない:

#define _ACD 5, 5, 5, 30

#define DEFAULT_NETWORK_TOKEN_KEY_CLASS   _ACD 

#define DEFAULT_NETWORK_TOKEN_KEY { DEFAULT_NETWORK_TOKEN_KEY_CLASS }

DEFAULT_NETWORK_TOKEN_KEY_CLASSマクロのみを使用して、const unsignedchar[]で_ACDを文字列化する方法。

const uint8 startMsg[] = ?? DEFAULT_NETWORK_TOKEN_KEY_CLASS ;

結果は_ACDのみになります。

ここで_ACDを取得するための正しいマクロ展開は何ですか。配列を持つマクロを#definea_macro{5,7,7,97}として文字列化する方法のコンテキストでは?

4

1 に答える 1

11

(本当に正当な理由なしに C プリプロセッサを悪用しないという標準的な免責事項がここに適用されます。)

やりたいことは必ず実現できます。STRINGIFYマクロと少しのマクロ間接化が必要です。

通常、STRINGIFYC プリプロセッサが引数を文字列化する前に展開できるように、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;
}
于 2012-07-27T19:12:25.433 に答える