I am currently using Visual Studio 2022 Update 17.1.6, and I found something interesting with exporting type alias. For reasons I don't understand, when I export a type alias for some data type such as std::vector<std::string>
in a module interface file, I can use both std::vector<>
and std::string
in the file that imported it. For example:
modInterface.ixx
export module words;
import <iostream>
import <vector>;
import <string>;
...
export using Words = std::vector<std::string>;
...
In an internal partition:
modInternalPartition.cpp
module words:wordsIP;
import words;
//This compiles as expected
Words wordStorage;
//Why does my compiler sees below as correct, and compiles it without error?
std::vector<int> numStorage = { 1, 2, 3, 4 };
//Why does my compiler also sees below as correct, and compiles it without error?
std::string text = "This dish is tasty";
//This would produce an error, which is expected since I did not export import <iostream> in modInterface.ixx
std::cout << text;
...
My first thought was that since Words
is a type alias, exporting it would mean exporting std::vector<>
and std::string
, but since std::vector<>
is a template, why is it not the case that only the instantiation of it (std::vector<std::string>
) is exported?
CodePudding user response:
When one part of a module imports another, all declarations not affected by internal linkage are available as if they were exported. That applies even to import
declarations (and to the implicit import of a module by its non-partition implementation units), so the import <vector>;
etc. are available in the words:wordsIP
partition. The export
has nothing to do with it at all.
CodePudding user response:
Here's a funny thing about modules: export
declarations only matter for code outside of a module.
If you import a module unit that is part of the same module as yourself, you have access to all of the declarations in that module unit. This allows you to have "private" declarations which are not exported to the module's interface, but are still accessible to other code within the module. This includes module imports:
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.
Header units are not special in this regard. You imported those header units, so they are imported by your primary module interface. Therefore, any module implementations for that module that import your primary module interface will see them.