预处理器宏字符串化
preprocessor macro stringify
我正在尝试了解预处理器。
为什么波纹管预处理器宏中的一个不起作用而另一个却起作用
#pragma 和 _Pragma 有什么区别
为什么我们用 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__)
来源:
https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
http://forums.codeguru.com/showthread.php?215151-LINE-MACRO-to-string-literal&p=613574#post613574
why one of the bellow preprocessor macro doesn't work while the other does
虽然预处理器将扩展当前扩展产生的大多数宏,但它只会执行一个扩展步骤。所以 ASTRINGZ(__FILE__)
在传递到 TODO
.
的字符串化之前不会一直扩展
您有多种选择来处理这个问题,最简单的是依靠 __FILE__
已经是 字符串文字这一事实。
#define msg(s) TODO( s " - @ - " __FILE__)
但是如果你想尝试宏扩展,你可以试试延迟技术。这将延迟 TODO
本身实际展开的时间,并给参数时间来展开它们自己。
#define EMPTY()
#define DEFER(m) m EMPTY EMPTY()()
#define msg(s) DEFER(TODO)( s " - @ - " ASTRINGZ(__FILE__))
以上使得 ( s " - @ - " ASTRINGZ(__FILE__))
不是宏的参数,因此 ASTRINGZ
将被扩展。然而,DEFER(TODO)
是一个宏,因此它将扩展为 TODO EMPTY EMPTY()()
。这将需要两个以上的扩展周期(每个 EMPTY()
for TODO (...)
被交还给预处理器。此时一切都应该适当扩展。
what is the difference between #pragma and _Pragma
_Pragma
是提供编译器特定 pragma 指令的另一种标准方法。区别在于 _Pragma
可以是宏扩展的结果,而 #pragma
可能不是指令。
why do we wrap STRINGZ with ASTRINGZ?
这是另一种延迟技巧。如果 ASTRINGZ
的参数本身是一些非平凡的预处理器扩展的结果。
我正在尝试了解预处理器。
为什么波纹管预处理器宏中的一个不起作用而另一个却起作用
#pragma 和 _Pragma 有什么区别
为什么我们用 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__)
来源:
https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
http://forums.codeguru.com/showthread.php?215151-LINE-MACRO-to-string-literal&p=613574#post613574
why one of the bellow preprocessor macro doesn't work while the other does
虽然预处理器将扩展当前扩展产生的大多数宏,但它只会执行一个扩展步骤。所以 ASTRINGZ(__FILE__)
在传递到 TODO
.
您有多种选择来处理这个问题,最简单的是依靠 __FILE__
已经是 字符串文字这一事实。
#define msg(s) TODO( s " - @ - " __FILE__)
但是如果你想尝试宏扩展,你可以试试延迟技术。这将延迟 TODO
本身实际展开的时间,并给参数时间来展开它们自己。
#define EMPTY()
#define DEFER(m) m EMPTY EMPTY()()
#define msg(s) DEFER(TODO)( s " - @ - " ASTRINGZ(__FILE__))
以上使得 ( s " - @ - " ASTRINGZ(__FILE__))
不是宏的参数,因此 ASTRINGZ
将被扩展。然而,DEFER(TODO)
是一个宏,因此它将扩展为 TODO EMPTY EMPTY()()
。这将需要两个以上的扩展周期(每个 EMPTY()
for TODO (...)
被交还给预处理器。此时一切都应该适当扩展。
what is the difference between #pragma and _Pragma
_Pragma
是提供编译器特定 pragma 指令的另一种标准方法。区别在于 _Pragma
可以是宏扩展的结果,而 #pragma
可能不是指令。
why do we wrap STRINGZ with ASTRINGZ?
这是另一种延迟技巧。如果 ASTRINGZ
的参数本身是一些非平凡的预处理器扩展的结果。