【发布时间】:2011-07-18 07:07:17
【问题描述】:
我遇到了这个断言示例,想知道# 是干什么用的:
#define ASSERT( x ) if ( !( x ) ) { \
int *p = NULL; \
DBGPRINTF("Assert failed: [%s]\r\n Halting.", #x); \
*p=1; \
}
【问题讨论】:
标签: c++ c c-preprocessor stringification
我遇到了这个断言示例,想知道# 是干什么用的:
#define ASSERT( x ) if ( !( x ) ) { \
int *p = NULL; \
DBGPRINTF("Assert failed: [%s]\r\n Halting.", #x); \
*p=1; \
}
【问题讨论】:
标签: c++ c c-preprocessor stringification
它是“stringize”预处理运算符。
它将标记作为参数传递给宏参数x,并将它们转换为字符串文字。
#define ASSERT(x) #x
ASSERT(a b c d)
// is replaced by
"a b c d"
【讨论】:
#x 是字符串化指令
#define Stringify(x) #x
表示Stringify(abc) 将替换为"abc"
如
#define initVarWithItsOwnName(x) const char* p = #x
int main()
{
initVarWithItsOwnName(Var);
std::cout << Var; //will print Var
}
【讨论】:
# 是预处理器的"stringizing" operator。它将宏参数转换为字符串文字。如果您调用了ASSERT(foo >= 32),则在评估宏期间#x 将扩展为"foo >= 32"。
【讨论】:
这是一个名为stringification 的预处理器功能。它
用实际参数的文字文本替换[宏参数],转换为字符串常量。
【讨论】:
# 是第 6.10.3.2 节 (C99) 和第 16.3.2 节中定义的字符串化运算符。 (C++03)
它将宏参数转换为字符串文字,而不扩展参数定义。
如果替换结果不是有效的字符串文字,则 行为是未定义。 # 运算符的求值顺序是未指定。
例如,在语法上,字符串文字中反斜杠字符的出现仅限于转义序列。
在以下示例中:
1 #define mkstr(x) # x
2 char *p = mkstr(a \ b);
/* "a \ b" violates the syntax of string literals */
# 运算符的结果不必是"a \ b"。
【讨论】:
mkstr("a") 将产生"\"a\"",而不是""a""。也许这不适用于无关的非空白标记?
mkstr(a\b)。没有多余的空白。
"\\" 变为 "\"\\\\\""。
【讨论】:
您所看到的称为字符串化。它允许您将宏的参数转换为字符串文字。你可以在这里http://gcc.gnu.org/onlinedocs/cpp/Stringification.html阅读更多信息。
【讨论】: