【问题标题】:Split function-like macro call between two source files在两个源文件之间拆分类似函数的宏调用
【发布时间】:2022-01-05 04:59:07
【问题描述】:

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",但我实际上在标准中找不到任何禁止它。

想法?

【问题讨论】:

  • Clang 没有抱怨。无法在 Godbolt 中测试 GCC,除非它有某种方式提供用户定义的头文件。有人用 GCC 测试这个吗?
  • 我非常确信有一条规则 somewhere 表示宏调用可能不会在包含的文件中开始并继续到包含它的文件中,但我查看了我自己通过 6.10 并找不到它,这可能意味着它隐藏在 DR 响应中并且从未被纳入标准文本(无论如何从 N1570 开始)。希望其他人可以给出更明确的答案。
  • (顺便说一句,OP,不要这样做。如果你这样做,一群暴徒会拿着干草叉和火把出现在你家门口。)
  • @JohnBollinger 记录。删除了 c99 标签

标签: c gcc language-lawyer c-preprocessor


【解决方案1】:

5.1.1.2 翻译阶段
(1.4) 执行预处理指令,扩展宏调用,并执行_Pragma 一元运算符表达式... #include 预处理指令导致命名的头文件或源文件从阶段 1 开始处理 通过第 4 阶段,递归。然后删除所有预处理指令。

我相信这意味着每个包含的标头都经过单独预处理,然后“合并”到整个翻译单元中。正是在这一点上,一个不完整的类似函数的宏调用将是格式错误的:

6.10.3/4 ...应该存在一个终止调用的)预处理令牌。

【讨论】:

    【解决方案2】:

    这...

    #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. 执行预处理指令,扩展宏调用,并执行_Pragma 一元运算符表达式。如果一个 匹配通用字符语法的字符序列 名称由令牌连接(6.10.3.3)产生,行为是 不明确的。 #include 预处理指令导致命名为 从阶段 1 到阶段 4 处理的头文件或源文件, 递归。然后删除所有预处理指令。

    #include一个文件导致该文件从阶段 1 到阶段 4 被处理意味着,除其他外,在该文件中开始的任何类似函数的宏调用必须是完整的在那个文件中。 #include 指令之后的预处理标记与包含文件的预处理无关。

    第 6.10.3/10 段(部分)说:

    类函数宏名称的每个后续实例后跟一个 ( 作为下一个预处理令牌引入序列 预处理被替换列表替换的令牌 定义(宏的调用)。

    这并没有留下解释的余地​​

    DECORATE(
    

    macro_call.h 中作为DECORATE() 调用的开头以外的任何内容,但无法处理,因为

    被替换的预处理标记序列被匹配的)预处理标记终止

    事实上,第 6.10.3/4 段要求有这样的令牌, 但文件中没有出现这样的预处理标记。

    【讨论】:

      猜你喜欢
      • 2016-03-15
      • 1970-01-01
      • 2014-01-11
      • 1970-01-01
      • 2019-02-15
      • 1970-01-01
      • 2019-04-11
      • 2020-02-29
      • 2018-01-23
      相关资源
      最近更新 更多