字符串化 - 它是如何工作的?

时间:2013-06-07 17:25:10

标签: c++ c c-preprocessor stringification

我知道:

#define foo 4  
#define str(s) #s
带有str(foo)

写出:"foo",因为stringify首先执行文本扩展,但是这样:

 #define xstr(s) str(s)
 #define str(s) #s
 #define foo 4

xstr(foo)写出:"4"

为什么呢?该过程涉及哪些步骤?

2 个答案:

答案 0 :(得分:54)

宏观扩张的相关步骤是(根据C 2011 [n1570] 6.10.3.1和C ++ 1998 16.3.1):

  1. 处理前面有###
  2. 的令牌
  3. 将宏替换应用于每个参数。
  4. 将每个参数替换为上述宏替换的相应结果。
  5. 重新扫描以获取更多宏。
  6. 因此,对于xstr(foo),我们有:

    1. 替换文字str(s)不包含###,因此不会发生任何事情。
    2. 参数foo已替换为4,因此就好像使用了xstr(4)一样。
    3. 在替换文字str(s)中,参数s已替换为4,生成str(4)
    4. str(4)已重新扫描。 (结果步骤产生”4”。)
    5. 请注意,str(foo)的问题在于步骤1(将foo替换为4)在步骤1之后,将参数更改为字符串。在第1步中,foo仍为foo;它尚未替换为4,因此结果为”foo”

      这就是使用辅助宏的原因。它允许我们执行第2步,然后使用另一个宏执行第1步。

答案 1 :(得分:12)

第一种情况

  1. 评估str(foo):用str(foo)代替#foo,即"foo"
  2. 第二种情况

    1. 评估xstr(foo):用xstr(foo)代替str(<foo-value>),即str(4)
    2. 评估str(4):用str(4)代替#4,即"4"
    3. 通常,

      预处理器评估宏函数扩展宏变量,直到它无需评估

      如果你定义

      #define xstr(s) str(s) + 1
      #define str(s) s + 1
      

      在以下代码中

      #define foo 4
      
      int main()
      {
          std::cout << str(foo) << '\n' 
                    << xstr(foo) << '\n' ;
      
      } 
      

      它会评估为

      第一个字符串

      1. str(foo)代替<foo-value> + 1,即4 + 1
      2. 没有什么可以替代的。精加工。
      3. 结果是4 + 1

        第二个字符串

        1. xstr(foo)代替str(<foo-value>) + 1,即str(4) + 1
        2. str(4)代替<4-value> + 1,即4 + 1
        3. 无需替代。
        4. 结果是4 + 1 + 1