gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 20:01:20 25 4
gpt4 key购买 nike

面对是否可以在预处理器中选择 #include 的问题,我立即认为不可能
.. 后来才发现这确实是可能的,你只需要注意参数扩展(例如 Boost.Preprocessor 可以处理)。

虽然我会尽可能避免对 include 执行此操作,但我想知道为什么这样做有效。目前,我未能对 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>

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

最佳答案

来自 C++ 2003 草案的 § 16.2-4(“源文件包含”):

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 也是如此。

上面说的“前两种形式”是# 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

#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 指出:

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替换后。

综上所述,对#if做了宏展开, #elif , #include , #line ,宏函数的参数和替换时的宏函数体。我认为这就是一切。

关于c++ - 宏作为预处理器指令的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1736654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com