c++ - 分区模块是否由主模块接口(interface)单元输出?

标签 c++ language-lawyer c++20 c++-modules

考虑这个例子

// translation C
export module M:C;
// translation U
export module M:B;
import :C;
// translation unit T
export module M;
export import :B;  // #1 imports `M:B` and `M:C`

[module.unit] 说

All module partitions of a module that are module interface units shall be directly or indirectly exported by the primary module interface unit ([module.import]). No diagnostic is required for a violation of these rules.

[module.import] p7 说

When a module-import-declaration imports a translation unit T, it also imports all translation units imported by exported module-import-declarations in T; such translation units are said to be exported by T. Additionally, when a module-import-declaration in a module unit of some module M imports another module unit U of M, it also imports all translation units imported by non-exported module-import-declarations in the module unit purview of U. These rules can in turn lead to the importation of yet more translation units.

第一部分说如果 T 导入 中导出的 module-import-declarationT 导出翻译单元> 他们。

由于 U 中有一个未导出的模块导入声明 import :C;,并且 module- M 的主要模块单元 #1 处的 import-declaration 导入 M 的另一个模块单元 U code>,因此 #1 处的 module-import-declarationimports C,根据后面的部分“另外”。

同样,由于 T#1 处的 module-import-declaration 被导出,它直接导入 M:B间接导入 M:C,因此M:BM:C T 导出。

因此,所有分区模块接口(interface)单元都由主模块接口(interface)单元导出。但是用GCC编译例子:g++ -std=c++20 -fmodules-ts c.cpp u.cpp t.cpp,报错:

interface partition is not exported

是不是GCC的bug,还是C分区确实没有被T导出,这里的规则不明确?

更新:

// file c
export module C;
export int fun(){return 0;}

// file b
export module M:B;
import C;

// file a
export module M;
export import :B;  // #1
int d = fun();  // #2

// file main
import M;
int main(){}

#2 在此 example是良构的。原因是在 #1 导出的 module-import-declaration 不仅 imports M:B 而且还导入C 这样函数 fun 可以在 #2 找到。那么,为什么我们不同意 TU C imported#1 处导出的 module-import-declaration> TU中的a是由a导出的,下面说的到底是什么?

all translation units imported by exported module-import-declarations in T; such translation units are said to be exported by T.

这是标准在这里含糊不清的部分,即使 GCC 实现了无法从规则中读取的正确内容。

最佳答案

Also, since there is a non-exported module-import-declaration import :C; in U, the module-import-declaration at #1 that imports U therefore also imports C.

这与您引用的标准所说的相反。 “由 T 导出”的定义需要使用“在 T 中导出的模块导入声明”。

您可能因为使用了非指示性名称而感到困惑。我将使用实际的模块名称而不是您的翻译单元名称。这里我们关心的是模块MM:BM:C之间的关系。 M 导入 M:B,后者导入 M:C。然而,当应用标准的措辞时,我们可以看到 M:CM:B import 没有使用“exported module-import-declaration”。因此,M:C 不是由 M:B“导出”。

M导入和导出M:B时,由此导出的翻译单元集不包括M:C 因为它不是由 M:B“导出”。

但是M:C是模块M的一个接口(interface)分区。根据您引用的第一条规则,它必须由 M 直接或间接“导出”。

因此,您的代码格式错误。

关于c++ - 分区模块是否由主模块接口(interface)单元输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72625608/

相关文章:

c++ - 没有从 'int' 到 'Student' 的可行转换

c++ - 如何在 C++ Builder 4.0 中创建 BPL 文件?

c++ - 具有默认参数的类模板作为较小参数的模板模板类参数的不一致处理

c++ - 使用 `void*` 将右值引用绑定(bind)到左值

用于类型和非类型模板的 c++ auto

c++ 模板和析构函数问题

c++ - 如何仅将宏扩展为C++文件的预处理步骤

c++ - 当 sizeof(long) == sizeof(int) 时 long* 和 int* 之间的转换

c++ - 容器类型的 View

使用概念具有特定值类型的任何容器的 C++ 迭代器