简体   繁体   English

预处理器宏字符串化

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM