代码之家  ›  专栏  ›  技术社区  ›  Georg Fritzsche

宏作为预处理器指令的参数

  •  3
  • Georg Fritzsche  · 技术社区  · 16 年前

    #include .
    .. 只是后来才发现这确实是可能的,您只需要注意参数扩展(例如Boost.Preprocessor可以处理)。

    如果可能的话,我会避免为includes实际这么做,但我想知道为什么会这样。目前我在C++中没有得到有用的理解。 标准
    任何预处理器指令都允许参数化宏吗?(除 #define / #undef
    是否有人可以参考哪些地方允许这样做并对其进行总结?

    #include <boost/preprocessor/cat.hpp>
    #include <boost/preprocessor/stringize.hpp>
    
    #define INC_LOCAL(a,b)  BOOST_PP_STRINGIZE(BOOST_PP_CAT(BOOST_PP_CAT(a,b),.h))
    #define INC_GLOBAL(a,b) BOOST_PP_CAT(BOOST_PP_CAT(<,a),BOOST_PP_CAT(b,>))
    
    #include INC_LOCAL(loc,al)   // #include "local.h"
    #include INC_GLOBAL(vect,or) // #include <vector>
    

    更新 : 参考 标准,澄清问题。

    2 回复  |  直到 10 年前
        1
  •  7
  •   outis    16 年前

    从第16.2-4页(“源文件包含”)的C++ 2003草案:

    # include pp-tokens new-line 
    

    (与前两种形式中的一种不匹配)是允许的。之后的预处理令牌 include 在指令中,与在普通文本中一样进行处理(当前定义为宏名称的每个标识符都由其预处理标记的替换列表替换)。

    C99的§6.10.2-4也有同样的规定。

    上面提到的“前两种形式”是 # include <h-char-sequence> 和 # include "q-char-sequence"

    identifier

    # if constant-expression new-line [group] 
    # ifdef identifier new-line [group] 
    # ifndef identifier new-line [group] 
    # elif constant-expression new-line [group] 
    # else new-line [group] 
    # endif new-line 
    # include pp-tokens new-line 
    # define identifier replacement-list new-line 
    # define identifier lparen [identifier-list] ) replacement-list new-line 
    # undef identifier new-line 
    # line pp-tokens new-line 
    # error [pp-tokens] new-line 
    # pragma [pp-tokens] new-line 
    # new-line 
    

    #line #error (C++§16.5/C§6.10.5)和 #pragma

    如果#预处理令牌后跟标识符,在预处理指令可以开始的位置出现,则该标识符不受宏替换的约束。

    replacement-list ,它们是第一个展开的宏。类似地,C++ + 16.3.4/C PRO.67.3.4预处理器宏扩展了 替换列表 换人后。

    总之,宏扩展是为 #if , #elif #include #线 ,替换时宏函数的参数和宏函数体。我想这就是一切。

        2
  •  2
  •   Alex Martelli    16 年前

    这是C预处理器的一个非常基本的特性——例如,一个指令,如 #ifdef 毫无意义 除了 #ifdef 可能地

    我不知道ISO C标准的章节如何帮助你——我记得,C++标准没有改变预处理器的操作。