Geo*_*che 3 c++ macros c-preprocessor
面对是否有可能#include在预处理器中选择s的问题,我立即认为不可能.
..后来发现它确实是可能的,你只需要注意参数扩展(例如Boost.Preprocessor可以处理).
虽然如果可能的话,我会避免实际为包含内容做这件事,但我想知道为什么这样做.目前,我无法在C++或C标准中获得有用的理解.
参数化宏是否允许任何预处理器指令?(除了#define/ #undef)
有人可以参考允许的地方并进行总结吗?
为简单起见,使用Boost.Preprocessor的好奇示例:
#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>
Run Code Online (Sandbox Code Playgroud)
更新:参考C标准,澄清问题.
来自C++ 2003草案的§16.2-4("源文件包含"):
表单的预处理指令
Run Code Online (Sandbox Code Playgroud)# include pp-tokens new-line(允许与前两种形式中的一种不匹配).
include指令中的预处理标记与正常文本一样处理(当前定义为宏名称的每个标识符由其预处理标记的替换列表替换).
C99的第6.10.2-4段说同样的话.
上面提到的"前两种形式"是# include <h-char-sequence>和# include "q-char-sequence".该部分似乎过于简单而无法概括.
对于其他指令,不对任何identifier预处理令牌执行宏扩展(请注意,此行为不是由语法定义的,而是由C++§16/C§6.10组成):
# 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
Run Code Online (Sandbox Code Playgroud)
#line由C++§16.4-5/C§6.10.4-5明确地进行宏扩展.膨胀为#error(C++§16.5/C§6.10.5)和#pragma(C++§16.6/C§6.10.6)没有提及.C++§16.3-7/ C 6.10.3-8规定:
如果#预处理标记(后跟标识符)在预处理指令可以开始的位置以词汇方式发生,则标识符不受宏替换的影响.
C++§16.3.1/C§6.10.3.1-1告诉我们,当宏函数的参数被替换为replacement-list,它们首先是宏扩展的.类似地,C++§16.3.4/C§6.10.3.4使预处理器宏扩展replacement-list后替换.
总之,宏扩展为完成#if,#elif,#include,#line,的参数的宏功能,并且当取代的宏功能的身体.我认为这就是一切.