预处理:定义“import”的简写是否合法?

He3*_*xxx 2 c++ language-lawyer c-preprocessor c++20

为了解决代码高尔夫挑战,我想生成尽可能小的代码。我有定义一个简写的想法import

#define I import
I<vector>;
Run Code Online (Sandbox Code Playgroud)

简短的 Godbolt 示例

当然,这里的意图是重用I以实际节省字节。

这在 C++20 中合法吗?

想法/到目前为止我发现的:

  • 根据 cppreference,“模块和导入指令也是预处理指令”。所以我认为这可以归结为我们是否保证预处理器首先必须用我们的定义替换 I 的问题?
  • 我认为处理import指令应该在翻译阶段 4 中进行,并且对于整个阶段,I除非另有说明([cpp.pre]-7),否则不应进行宏扩展。对于这种情况,是否另有规定?
  • 这有可能作为预处理器重新扫描的一部分吗?
  • Godbolt 上的 Clang 和 GCC 无法编译,但 AFAIK 尚不支持在没有额外步骤的情况下导入标准库头文件,并且它们给出了与速记版本相同的错误消息,这表明它可以工作(?)
  • 相同的方法,但使用include而不是import,不适用于 gcc 和 clang,因此可能不合法。

T.C*_*.C. 10

不。

[cpp.pre]/1 :

预处理指令由预处理标记,其满足以下约束的序列的:在翻译阶段4的开始,该序列中的第一令牌,称为 指令导入令牌,便从在源文件中的第一个字符(可选在不包含换行符的空格之后)或在包含至少一个换行符的空格之后,并且是 [...]

在任何宏替换之前,在翻译阶段 4 开始时确定预处理方向性。因此,I<vector>;不被识别为指令,并且importfrom 宏扩展I不会import-keyword token替换。这反过来意味着它在翻译阶段 7 期间不被识别为模块导入声明,而只是在import没有事先声明的情况下使用标识符的错误格式尝试。

这种舞蹈的重点是确保构建系统可以知道文件的依赖关系,而不必完全预处理文件——如果可以通过宏替换形成导入,这将是必需的。