预处理器宏扩展到另一个预处理器指令

发布于 2024-08-01 18:08:29 字数 306 浏览 14 评论 0原文

最初我认为我需要这个,但最终我避免了它。 然而,我的好奇心(以及对知识的渴望,嗯)让我问:

预处理器宏是否可以

#include "MyClass.h"

INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass)

扩展到另一个包含,例如

#include "MyClass.h"

#include "FooTemplate.h"
template class FooTemplate<MyClass>;

Initially I thought I needed this, but I eventually avoided it. However, my curiosity (and appetite for knowledge, hum) make me ask:

Can a preprocessor macro, for instance in

#include "MyClass.h"

INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass)

expand to another include, like in

#include "MyClass.h"

#include "FooTemplate.h"
template class FooTemplate<MyClass>;

?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浊酒尽余欢 2024-08-08 18:08:29

我相信这是不可能的,这是因为预处理器是单通道。 因此它不能发出其他预处理器指令。

具体来说,来自 C99 标准(6.10.3.4 第 3 段):

3 结果完全
宏替换的预处理标记
序列不被处理为
预处理指令即使它
类似于一个,...

有趣的是,这就是为什么一元 _Pragma 运算符被添加到 c99 中。 因为 #pragma 无法由宏发出,但 _Pragma 可以。

I believe that cannot be done, this is because the pre-processor is single pass. So it cannot emit other preprocessor directives.

Specifically, from the C99 Standard (6.10.3.4 paragraph 3):

3 The resulting completely
macro-replaced preprocessing token
sequence is not processed as a
preprocessing directive even if it
resembles one, ...

Interestingly enough, This is why the unary _Pragma operator was added to c99. Because #pragma could not be emited by macros, but _Pragma can.

佼人 2024-08-08 18:08:29

C 标准对预处理指令有这样的规定(C99 - 6.10(2) - 预处理指令):

预处理指令由一系列预处理标记组成,这些标记以
# 预处理标记(在翻译阶段 4 开始时)
...

和 ​​(C99 - 6.10(7)):

预处理指令中的预处理标记不受宏的约束
除非另有说明,否则可扩展。

示例:

<前><代码>#define EMPTY
EMPTY # include;

第二行上的预处理标记序列不是预处理指令,因为它在翻译阶段 4 开始时不是以 # 开头,尽管在宏 EMPTY 被替换后它会这样做

所以,不,宏不能扩展为“#include”预处理指令。 这些指令需要在翻译阶段 4 开始时就位(当处理这些指令时发生预处理)。 由于宏扩展发生在第 4 阶段,因此宏不能导致某些内容在第 4 阶段开始时存在。

不过,我想指出,以下确实有效:

#ifdef WIN32
#define PLATFORM_HEADER "platform/windows/platform.h"
#else
#define PLATFORM_HEADER "platform/linux/platform.h"

#include PLATFORM_HEADER

因为 C 标准说这(C99,6.10.2(4) - 源文件包含):

表单的预处理指令

# include pp-tokens 换行符 
  

允许

(与前面两种形式之一不匹配)。 预处理
包含在指令中后的标记将像普通文本一样进行处理。 (每个
当前定义为宏名称的标识符被其替换列表替换
预处理标记。)

The C standard says this about preprocessing directives (C99 - 6.10(2) - Preprocessing directives):

A preprocessing directive consists of a sequence of preprocessing tokens that begins with
a # preprocessing token that (at the start of translation phase 4)
...

and (C99 - 6.10(7)):

The preprocessing tokens within a preprocessing directive are not subject to macro
expansion unless otherwise stated.

EXAMPLE In:

#define EMPTY
EMPTY # include <file.h>

the sequence of preprocessing tokens on the second line is not a preprocessing directive, because it does not begin with a # at the start of translation phase 4, even though it will do so after the macro EMPTY has been replaced

So, no, macros cannot expand into a '#include' preprocessing directive. Those directives need to be in place at the start of translation phase 4 (when handling those directives takes place preprocessing happens). Since macro expansion occurs during phase 4, macros can't cause something to exist at the start of phase 4.

I'd like to point out however, that the following does work:

#ifdef WIN32
#define PLATFORM_HEADER "platform/windows/platform.h"
#else
#define PLATFORM_HEADER "platform/linux/platform.h"

#include PLATFORM_HEADER

because the C standard says this (C99, 6.10.2(4) - Source file inclusion):

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.)

凉月流沐 2024-08-08 18:08:29

所有预处理器指令都会在宏扩展开始之前进行解释,因此不能将宏扩展为 #include 指令并对其进行这样的解释。 相反,它将被解释为(错误的)C++ 代码。

All preprocessor directives are interpreted before macro expansion begins, so no, you cannot have a macro expand into an #include directive and have it be interpreted as such. Instead, it will be interpreted as (erroneous) C++ code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文