考虑一下这个例子
// 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说
模块的所有模块分区都是模块接口单元,由主模块接口单元 (module.import)直接或间接导出。违反这些规则不需要诊断。
module.import p7说
当模块-导入-声明导入翻译单元T时,它还通过导出模块导入所有翻译单元导入的-导入-在T中的导入声明;这样的翻译单元被称为由T导出。另外,当某个模块M的模块单元中的模块导入声明导入另一个模块单元U的时候,还导入了由非导出模块导入的所有转换单元-导入声明在U的模块单元权限中。这些规则反过来又会导致输入更多的翻译单位。
第一部分说,如果一个导出的module-import-declaration在T imports中导出翻译单元,那么就会导出翻译单元。
由于在module-import-declaration中有一个未导出的模块-导入-声明import :C;,而M主模块单元中的#1则导入了M的另一个模块单元U,因此#1的#1也根据“附加”后的部分导入 C。
同样,由于#1的T中的模块导入声明是导出的,所以直接导入 M:B,间接导入 M:C,因此M:B和M:C由T导出。
因此,所有分区模块接口单元都由主模块接口单元导出。但是,当使用GCC:g++ -std=c++20 -fmodules-ts c.cpp u.cpp t.cpp编译示例时,它会报告错误:
interface partition is not exported这是GCC的错误,还是分区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在这个示例中是格式良好的.这是因为在#1上导出的模块导入声明不仅是导入 M:B,而且是导入C,这样就可以在#2上找到函数fun。那么,为什么我们不同意TU C 通过导出的模块导入-- TU a中#1的导入-声明是由a导出的,这在下面是这样说的?
所有的翻译单位通过导出的模块导入;这样的翻译单元据说是由T导出的。
这是标准的一部分,在这里是模棱两可的,即使GCC实现了一些不能从规则中看出来的正确的东西。
发布于 2022-06-15 05:15:30
另外,由于有一个非导出模块-导入-声明导入: C;在U中,在#1处的模块-导入-声明
这与你所引用的标准正好相反。“由T导出”的定义要求使用“导出模块--T中的导入-声明”。
你可能会因为使用非指示性的名字而感到困惑。我将使用实际的模块名称,而不是您的翻译单元名称。这里我们关心的是模块M、M:B和M:C之间的关系。M导入M:B,后者导入M:C。然而,在应用该标准的措辞时,我们可以看到,M:B导入M:C并不使用“导出模块-导入-声明”。因此,M:C不是“由”M:B导出的。
当M导入和导出M:B时,由此导出的翻译单元集不包括M:C,因为它不是“由”M:B导出的。
但是M:C是模块M的接口分区。根据您引用的第一条规则,它必须“由”M直接或间接导出。
因此,您的代码格式不正确。
https://stackoverflow.com/questions/72625608
复制相似问题