C99 Macro to build a quoted string literal after evaluation
I'm developing an embedded application in C99, and the project 开发者_开发技巧contains some integer constants defined like:
#define LEVEL1 0x0000
#define LEVEL2 (LEVEL1 + 1)
It has since become useful to keep track of these values for logging purposes, so I would like to use a macro to create a string literal from the evaluated versions of the above. For example:
strncpy(str, STRING(LEVEL2), len);
would ideally evaluate to
strncpy(str, "0x0001", len);
or even
strncpy(str, "0001", len);
Using a two-stage macro with the # operator (as suggested by this question) almost works. It evaluates to
strncpy(str, "(LEVEL1 + 1)", len);
I would like to avoid the use of a run-time function - hence my attempt at a macro solution. Suggestions?
Since the pre-processor stringizer is a massive pain, you need to add a level of indirection both when creating version numbers and when stringizing:
#define STRING1(s) #s
#define STRING(s) STRING1(s)
#define LEVEL(x) x
#define LEVEL1 LEVEL(1)
#define LEVEL2 LEVEL(2)
printf(STRING(LEVEL2));
//2
You cannot do this because the preprocessor knows nothing about the C language so it cannot to evaluation.
I see two options to get the desired result:
Manual evaluation
Write your levels exactly as you want them to appear and use a single stringizer operator:
#define LEVEL1 0x0000
#define LEVEL2 0x0001
#define STRING(x) # x
strncpy(str, STRING(LEVEL2), len);
A disadvantage is that this is error prone and might clash with local coding conventions.
Runtime evaluation
Use one of the string format functions sprintf
or snprintf
.
#define LEVEL1 0x0000
#define LEVEL2 0x0001
char level[7];
snprintf(level, sizeof level, "%#06x", LEVEL2);
strncpy(str, level, len);
This has the runtime overhead you wanted to avoid.
精彩评论