宏作为预处理器伪指令的参数 [英] Macros as arguments to preprocessor directives

查看:88
本文介绍了宏作为预处理器伪指令的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

面对在预处理器中是否可以选择 #include 的问题,我立即认为不可能

..只有后来才发现它确实可能,你只需要注意参数扩展(例如Boost.Preprocessor可以照顾)。

Being faced with the question whether it's possible to choose #includes in the preprocessor I immediately thought not possible.
.. Only to later find out that it is indeed possible and you only need to watch out for argument expansions (which e.g. Boost.Preprocessor can take care of).

虽然我会避免实际上做包括如果可能的话,我想知道为什么这个工作。目前,我未能在C ++或 C 标准中获得有用的了解。

是否允许任何预处理器指令的参数化宏? ( #define / #undef 除外)

有人可以引用此处并允许总结它?

While I'd avoid actually doing that for includes if possible, I'd like to know why this works. At the moment I fail to get a useful understanding in the C++ or C standard.
Are parameterized macros allowed for any preprocessor-directive? (except #define/#undef)
Can someone reference where this is allowed and summarize it?

为了简单起见,使用Boost.Preprocessor的例子如下:

Example for the curious utilizing Boost.Preprocessor for simplicity:

#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>

更新
引用 C 标准,澄清的问题。

Update: Referenced C standard, clarified question.

推荐答案

从C ++ 2003草案的第16.2-4节(源文件包含 p>

From § 16.2-4 ("Source file inclusion") of C++ 2003 draft:


A preprocessing directive of the form

# include pp-tokens new-line

(与前两个表单中的一个不匹配)允许。在指令中的包括之后的预处理令牌与正常文本一样处理(每个标识符当前定义为宏名称,由其预处理令牌的替换列表替换)。

(that does not match one of the two previous forms) is permitted. The preprocessing tokens after include in the directive are processed just as in normal text (each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens).

C99的6.10.2-4说同样。

§ 6.10.2-4 of C99 says the same.

上述以前的两种形式是 #include< h-char-sequence> #includeq-char- code>。

The "two previous forms" mentioned above are # include <h-char-sequence> and # include "q-char-sequence". The section seems too simple to summarize.

对于其他指令,不会对任何标识符预处理执行宏扩展令牌(注意,这种行为不是由语法定义的,而是由C ++§16 / C§6.10定义的):

For other directives, macro expansion isn't performed on any identifier preprocessing token (note this behavior is not defined by the grammar, but by 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

#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状态:

#line is explicitly macro-expanded by C++ § 16.4-5 / C § 6.10.4-5. Expansion for #error (C++ § 16.5 / C § 6.10.5) and #pragma (C++ § 16.6 / C § 6.10.6) isn't mentioned. C++ § 16.3-7 / C 6.10.3-8 states:


如果一个#预处理令牌,后跟一个标识符,预处理指令可以开始的点,标识符不进行宏替换。

If a # preprocessing token, followed by an identifier, occurs lexically at the point at which a preprocessing directive could begin, the identifier is not subject to macro replacement.

C ++§16.3.1 / C§6.10.3.1-1告诉我们,当宏函数的参数被代入 replacement-list ,它们是第一个宏展开。类似地,C ++§16.3.4 / C§6.10.3.4具有预处理器宏 - 在替换后扩展 replacement-list

C++ § 16.3.1 / C § 6.10.3.1-1 tells us that when the arguments to a macro function are substituted into the replacement-list, they are first macro expanded. Similarly, C++ § 16.3.4 / C § 6.10.3.4 has the preprocessor macro-expand the replacement-list after substitution.

总之, #if #elif #include #line 是宏函数的参数和宏函数的主体。我想这就是一切。

In summary, macro expansion is done for #if, #elif, #include, #line, the arguments to a macro function and the body of a macro function when substituted. I think that's everything.

这篇关于宏作为预处理器伪指令的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆