在两个源文件之间拆分类似函数的宏调用
Split function-like macro call between two source files
C 标准中是否有任何内容阻止我执行以下操作?
// main.c
#define DECORATE(x) ***x***
#include "call_macro.h"
this is the text I want decorated)
// call_macro.h
DECORATE(
当 运行 它通过 gcc -E main.c
时,我希望得到
*** this is the text I want decorated***
相反,它抱怨macro_call.h:2: error: unterminated argument list invoking macro "DECORATE"
,但我实际上在标准中找不到任何禁令。
想法?
5.1.1.2 Translation phases
(1.4) Preprocessing directives are executed, macro invocations are expanded, and _Pragma
unary operator expressions are executed... A #include
preprocessing directive causes the named header or source file to be processed from phase 1
through phase 4, recursively. All preprocessing directives are then deleted.
我相信这是说每个包含的 header 在被“合并”到整个翻译单元之前都是单独预处理的。此时,不完整的 function-like 宏调用将是 ill-formed:
6.10.3/4 ... There shall exist a )
preprocessing token that terminates the invocation.
这个...
#define DECORATE(x) ***x***
... 是类函数宏 DECORATE
(C17 6.10.3/10) 的完整定义。它的范围是翻译单元的其余部分(没有相应的 #undef
;C17 6.10.3.5/1),包括源文件和头文件 #include
d 进入翻译单元的那部分。
为了使该宏的调用文本能够在包含文件中开始并在主文件中完成,#include
的模型需要类似于宏扩展的模型:被插入的包含文件的整个文本,然后在周围预处理标记的上下文中进行处理。但那是不是模型。
第 5.1.1.2/1 段描述了翻译 C 源代码的逻辑阶段。此处相关的是第 4 阶段(强调已添加):
- Preprocessing directives are executed, macro invocations are expanded, and
_Pragma
unary operator expressions are executed. If a
character sequence that matches the syntax of a universal character
name is produced by token concatenation (6.10.3.3), the behavior is
undefined. A #include
preprocessing directive causes the named
header or source file to be processed from phase 1 through phase 4,
recursively. All preprocessing directives are then deleted.
#include
ing 一个文件导致 该文件 从第 1 阶段到第 4 阶段进行处理意味着,除其他外,任何类似函数的宏调用该文件中的 starts 必须在该文件中完整。 #include
指令后的预处理标记与包含文件的预处理无关。
第 6.10.3/10 段说(部分):
Each subsequent instance of the function-like macro name followed by a
(
as the next preprocessing token introduces the sequence of
preprocessing tokens that is replaced by the replacement list in the
definition (an invocation of the macro).
那就不留解释的余地了
DECORATE(
在 macro_call.h
中作为 DECORATE()
调用开始以外的任何内容,但无法处理,因为
The replaced sequence of preprocessing tokens is terminated by the matching )
preprocessing token
事实上,第 6.10.3/4 段要求有这样一个令牌,
但是文件中没有出现这样的预处理标记。
C 标准中是否有任何内容阻止我执行以下操作?
// main.c
#define DECORATE(x) ***x***
#include "call_macro.h"
this is the text I want decorated)
// call_macro.h
DECORATE(
当 运行 它通过 gcc -E main.c
时,我希望得到
*** this is the text I want decorated***
相反,它抱怨macro_call.h:2: error: unterminated argument list invoking macro "DECORATE"
,但我实际上在标准中找不到任何禁令。
想法?
5.1.1.2 Translation phases
(1.4) Preprocessing directives are executed, macro invocations are expanded, and_Pragma
unary operator expressions are executed... A#include
preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted.
我相信这是说每个包含的 header 在被“合并”到整个翻译单元之前都是单独预处理的。此时,不完整的 function-like 宏调用将是 ill-formed:
6.10.3/4 ... There shall exist a
)
preprocessing token that terminates the invocation.
这个...
#define DECORATE(x) ***x***
... 是类函数宏 DECORATE
(C17 6.10.3/10) 的完整定义。它的范围是翻译单元的其余部分(没有相应的 #undef
;C17 6.10.3.5/1),包括源文件和头文件 #include
d 进入翻译单元的那部分。
为了使该宏的调用文本能够在包含文件中开始并在主文件中完成,#include
的模型需要类似于宏扩展的模型:被插入的包含文件的整个文本,然后在周围预处理标记的上下文中进行处理。但那是不是模型。
第 5.1.1.2/1 段描述了翻译 C 源代码的逻辑阶段。此处相关的是第 4 阶段(强调已添加):
- Preprocessing directives are executed, macro invocations are expanded, and
_Pragma
unary operator expressions are executed. If a character sequence that matches the syntax of a universal character name is produced by token concatenation (6.10.3.3), the behavior is undefined. A#include
preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted.
#include
ing 一个文件导致 该文件 从第 1 阶段到第 4 阶段进行处理意味着,除其他外,任何类似函数的宏调用该文件中的 starts 必须在该文件中完整。 #include
指令后的预处理标记与包含文件的预处理无关。
第 6.10.3/10 段说(部分):
Each subsequent instance of the function-like macro name followed by a
(
as the next preprocessing token introduces the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation of the macro).
那就不留解释的余地了
DECORATE(
在 macro_call.h
中作为 DECORATE()
调用开始以外的任何内容,但无法处理,因为
The replaced sequence of preprocessing tokens is terminated by the matching
)
preprocessing token
事实上,第 6.10.3/4 段要求有这样一个令牌, 但是文件中没有出现这样的预处理标记。