在两个源文件之间拆分类似函数的宏调用

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),包括源文件和头文件 #included 进入翻译单元的那部分。

为了使该宏的调用文本能够在包含文件中开始并在主文件中完成,#include 的模型需要类似于宏扩展的模型:被插入的包含文件的整个文本,然后在周围预处理标记的上下文中进行处理。但那是不是模型。

第 5.1.1.2/1 段描述了翻译 C 源代码的逻辑阶段。此处相关的是第 4 阶段(强调已添加):

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

#includeing 一个文件导致 该文件 从第 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 段要求有这样一个令牌, 但是文件中没有出现这样的预处理标记。