c++ - 奇怪的 C++ 预处理器行为

标签 c++ macros c-preprocessor stringification

<分区>

考虑以下代码:

#define M(x) #x
#define M2(x) M(x)

M(VAR);
M2(VAR);

使用以下命令行: cpp 测试.cpp -DVAR=xxx

我希望预处理器同时改变 M(x) 和 M2(x) 变成“xxx”。

但是只有M2被替换了。这是为什么?

最佳答案

当我尝试这个时,我得到:

"VAR";
"abc";

(您应该将其包含在您的问题中!)

As this page explains.

If you want to stringify the result of expansion of a macro argument, you have to use two levels of macros.

 #define xstr(s) str(s)
 #define str(s) #s
 #define foo 4
 str (foo)
      ==> "foo"
 xstr (foo)
      ==> xstr (4)
      ==> str (4)
      ==> "4"

s is stringified when it is used in str, so it is not macro-expanded first. But s is an ordinary argument to xstr, so it is completely macro-expanded before xstr itself is expanded. Therefore, by the time str gets to its argument, it has already been macro-expanded.

发生这种情况是因为预处理器的预扫描宏参数规则已解释 here :

该页面的重点是:

Macros that call other macros that stringify or concatenate.

If an argument is stringified or concatenated, the prescan does not occur. If you want to expand a macro, then stringify or concatenate its expansion, you can do that by causing one macro to call another macro that does the stringification or concatenation. For instance, if you have

      #define AFTERX(x) X_ ## x
      #define XAFTERX(x) AFTERX(x)
      #define TABLESIZE 1024
      #define BUFSIZE TABLESIZE 

AFTERX(BUFSIZE) expands to X_BUFSIZE, and XAFTERX(BUFSIZE) expands to X_1024. (Not to X_TABLESIZE. Prescan always does a complete expansion.)

关于c++ - 奇怪的 C++ 预处理器行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24412706/

相关文章:

c++ - reverse 函数不会反转类实例化的引用字符串

c - 为什么 UEFI 协议(protocol)头文件为单个协议(protocol) GUID 定义宏和外部全局变量?

c - 如何通过 C 预处理器 (cpp) 生成列表?

c++ - Boost Property_Tree 迭代器,如何处理它们?

c++ - 交错 std::map 插入和迭代

c++ - 内存管理 : arrays and dynamic allocation with new operator

C++,用define声明一个数组;怎么了? (简单快捷)

macros - 如何在 Rust 中向宏文档添加示例?

c++ - “卡住”一个表达式

c - 在 ## 运算符中将变量名称作为参数传递