[英]preprocessor macro stringify
im trying to understand preprocessor.我试图理解预处理器。
why one of the bellow preprocessor macro doesn't work while the other does为什么波纹管预处理器宏之一不起作用而另一个则起作用
what is the difference between #pragma and _Pragma #pragma 和 _Pragma 有什么区别
why do we wrap STRINGZ with ASTRINGZ?为什么我们用 ASTRINGZ 包裹 STRINGZ?
#define STRINGZ(x) #x
#define ASTRINGZ(x) STRINGZ(x)
#define DO_PRAGMA(x) _Pragma (#x)
#define TODO(x) DO_PRAGMA(message ("TODO - " #x))
#define msg(s) TODO( s " - @ - " ASTRINGZ(__FILE__))
msg ("This doesnt work")
#pragma message "but this does: " ASTRINGZ(__FILE__)
sources:来源:
https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
http://forums.codeguru.com/showthread.php?215151- LINE -MACRO-to-string-literal&p=613574#post613574 http://forums.codeguru.com/showthread.php?215151- LINE -macro到字串文本&P = 613574#post613574
why one of the bellow preprocessor macro doesn't work while the other does为什么波纹管预处理器宏之一不起作用而另一个则起作用
While the preprocessor will expand most further macros that result out of a current expansion, it will only do a single expansion step.虽然预处理器将扩展由当前扩展产生的大多数进一步宏,但它只会执行一个扩展步骤。 So ASTRINGZ(__FILE__)
is not going to be expanded all the way before being passed to the stringification of TODO
.所以ASTRINGZ(__FILE__)
在传递给TODO
的字符串化之前不会一直扩展。
You have several options to deal with this, the easiest is to rely on the fact __FILE__
is already a string literal.您有多种选择来处理这个问题,最简单的方法是依赖于事实__FILE__
已经是字符串文字。
#define msg(s) TODO( s " - @ - " __FILE__)
But if you wish to experiment with macro expansion, you can try a deferring technique.但是如果你想尝试宏扩展,你可以尝试延迟技术。 This will delay the moment TODO
is actually expanded itself, and give the arguments time to be expanded themselves.这将延迟TODO
实际扩展本身的时间,并给参数自己扩展的时间。
#define EMPTY()
#define DEFER(m) m EMPTY EMPTY()()
#define msg(s) DEFER(TODO)( s " - @ - " ASTRINGZ(__FILE__))
The above makes the ( s " - @ - " ASTRINGZ(__FILE__))
not be arguments to a macro, so ASTRINGZ
will be expanded.以上使( s " - @ - " ASTRINGZ(__FILE__))
不是宏的参数,因此ASTRINGZ
将被扩展。 DEFER(TODO)
is a macro however, so it will be expanded to TODO EMPTY EMPTY()()
.但是, DEFER(TODO)
是一个宏,因此它将扩展为TODO EMPTY EMPTY()()
。 It will take two more expansion cycles (each EMPTY()
for TODO (...)
to be handed back to the preprocessor. At which point everything should be properly expanded.还需要两个扩展周期(每个用于TODO (...)
EMPTY()
返回给预处理器。此时应该正确扩展所有内容。
what is the difference between #pragma and _Pragma #pragma 和 _Pragma 有什么区别
_Pragma
is another standard way to provide compiler specific pragma directive. _Pragma
是另一种提供编译器特定 pragma 指令的标准方式。 The difference is that _Pragma
can be the result of macro expansion, while #pragma
being a directive may not.不同之处在于_Pragma
可以是宏扩展的结果,而#pragma
作为指令可能不是。
why do we wrap STRINGZ with ASTRINGZ?为什么我们用 ASTRINGZ 包裹 STRINGZ?
It's another deferral technique.这是另一种延迟技术。 In case the argument to ASTRINGZ
is itself the result of some non-trivial preprocssor expansion.如果ASTRINGZ
的参数本身是一些非平凡的预处理器扩展的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.