P1881 中基于 C++ 模块的时代与潜在的#pragma-based 时代

Ant*_*hov 3 c++ standards pragma c++-modules

P1881提案中,提出了 C++ 代码的epoch(在模块级别)的概念。此类功能可以允许在模块级别自定义 C++ 语法和 C++ 行为,而不必破坏向后兼容性。提案中给出了更详细的动机

提案中的隐式转换示例

版本 1:没有时代,一切都编译正常

module ParticleMovement;

export void move(Particle&, float x, float y);

void moveExample()
{
    Particle p{};
    move(p, 3.42, 2.49);    // OK
}
Run Code Online (Sandbox Code Playgroud)

版本 2 :(epoch 2023假设在其中禁用隐式转换),代码格式错误:

epoch 2023;                 // Module-level switch
module ParticleMovement;

export void move(Particle&, float x, float y);

void moveExample()
{
    Particle p{};

    move(p, 3.42, 2.49);    // Compilation error

    move(p, 3.42f, 2.49f);  // OK, no implicit conversions
}
Run Code Online (Sandbox Code Playgroud)

这绝对看起来是一个有趣的提议,并且与简单地指定 compile 开关非常不同-std=c++XXX

然而,我想知道:

  • 在 P1881 中,时代被定义为模块级开关。除了方便之外,还有什么理由必须在模块级别?为什么不是翻译单元级别?
  • 因此,#pragma与基于模块的提案相比,这种行为是否可以通过's无缝实现,提供编译器支持,或者会引入严重的技术困难(从实现或使用的角度来看)?

说,沿线的东西:

#pragma epoch 2023;                 

export void move(Particle&, float x, float y);

void moveExample()
{
    Particle p{};

    move(p, 3.42, 2.49);    // Compilation error

    move(p, 3.42f, 2.49f);  // OK, no implicit conversions
}
Run Code Online (Sandbox Code Playgroud)

我已经阅读针对基于模块的实现的建议机制;但是,我不明白为什么它必须是 modules


同样相关:P1881 提案的作者 Vittorio Romeo 在 CppCon 2019 上的闪电演讲

Vit*_*meo 6

P1881 中epoch被定义为模块级开关。除了方便之外,还有什么理由必须在模块级别?为什么不是翻译单元级别?

理论上,epoch-declaration可以出现在任何级别,包括块范围甚至库范围。我为提案的第一次修订选择了模块,因为它们足够小,可以让大型项目从一个纪元优雅地迁移到另一个纪元,但也足够大,不会在同一个源文件中出现多个纪元。

在贝尔法斯特,有人建议模块分区可能是更好的选择,因为它们将允许单个模块逐渐迁移到更新的时代。


#pragma与基于模块的提案相比,这种行为是否可以通过's无缝实现,提供编译器支持,或者会引入严重的技术困难(从实现或使用的角度来看)?

原则上,我认为这是可能的。无论选择#pragmas 还是模块级声明,我相信编译器供应商仍然需要执行大量的工作来实现像 epoch 这样的任何东西(但我相信这是值得的)。


我不明白为什么它必须是模块。

它没有,真的。使用 P1881,我不仅尝试发明一种允许更改语法含义的机制,而且还尝试设想一种机制,该机制将非常适合 C++ 生态系统并促进良好的工程实践

我相信与模块级声明#pragma相比,块范围声明或 a有更多的误用机会。我还认为将 epoch 与模块联系起来将有助于开发人员在模块化现有代码库的同时考虑 epoch 迁移。

总的来说,该提案仍处于早期阶段,所有这些设计决策都可能会发生变化。反馈和想法总是受到赞赏 - 作者的电子邮件可以在论文中找到。