考虑一下:
#define STRINGIFY(A) #A
如果我后来写道:
STRINGIFY(hello)
编译器实际上看到了这个:
#hello
我认为#A
前面的额外哈希让我感到困惑。
答案 0 :(得分:15)
编译器看到的是:
"hello"
哈希是仅预处理程序的标记。
单个哈希对参数进行字符串化。
#define STRINGIFY(x) #x
STRINGIFY(hello)
取代
"hello"
双重哈希连接令牌:
#define CAT(a, b) a##b
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
STRINGIFY(CAT(hello,world))
被这个取代:
_STRINGIFY(helloworld)
然后由此:
"helloworld"
编辑: 正如Pubby指出的那样,这个例子是错误的,宏替换不起作用,但现在我纠正了它。
答案 1 :(得分:10)
不,编译器会将参数放在引号之间,结果如下:
"hello"
但是,请注意,在#
和##
附近不会发生宏替换,所以如果你真的需要对参数进行字符串化(,即使它是另一个宏)最好写两个宏,第一个用于扩展参数,另一个用于添加引号:
#define STRINGIFY(x) STRINGIFY_AUX(x)
#define STRINGIFY_AUX(x) #x
或者更一般地说,如果您的编译器支持可变参数宏(在C99中引入):
#define STRINGIFY(...) STRINGIFY_AUX(__VA_ARGS__)
#define STRINGIFY_AUX(...) #__VA_ARGS__
如果你真的需要一个类似函数的宏,在参数的开头粘贴#
,我认为你需要它来生成一个字符串(否则你会为编译器创建一个无效的标记),所以你可以简单地生成两个编译器将“粘贴”的字符串文字:
#include <stdio.h>
#define STRINGIFY(...) STRINGIFY_AUX(__VA_ARGS__)
#define STRINGIFY_AUX(...) #__VA_ARGS__
int main(void)
{
puts(STRINGIFY(#) STRINGIFY(hello));
}
main
主体在预处理器输出中将如下所示:
puts("#" "hello");
我希望这不是导致未定义行为的预处理器的一个模糊角落,但它不应该是一个问题,因为我们没有生成另一个预处理器指令。
答案 2 :(得分:9)
您可以使用-E
(*)标志(使用gcc / g ++)自行测试:
#define STRINGIFY(A) #A
int main(int argc, const char *argv[])
{
STRINGIFY(hello);
return 0;
}
g++ test.cpp -E
# 1 "test.cpp"
# 1 "<command-line>"
# 1 "test.cpp"
int main(int argc, const char *argv[])
{
"hello";
return 0;
}
(*):If you use the -E option, nothing is done except preprocessing.
- GCC Options Controlling the Preprocessor
答案 3 :(得分:3)
在此处找到了在预处理器中使用哈希的简单解释: