skip to Main Content

Visual Studio 2022 17.5 and later supports importing the C++23 standard library named module std by replacing all instances of #include <header> with import std; where <header> is a standard library header.

According to the tutorial there are some limitations, such as the following:

Don’t mix and match importing C++ standard library header files and named modules. For example, don’t #include <vector> and import std; in the same file.

Does this mean that if I use import std; in a file (by "file" I assume that the tutorial is referring to a .cpp file or other translation unit), then none of the non-standard library headers that it #includes is allowed to transitively #include a standard library header?

I’m pretty sure the answer is obviously yes, because after preprocessing, it doesn’t really matter whether an #include is transitive or not – its contents will end up in the .cpp file mixed with the import statement.

But then what can be done to prevent mixing besides an exhaustive search of all transitive #includes to see if there are any standard library headers? Especially if a project depends on something like Boost, it doesn’t seem that import std; will be a realistic option until Boost is itself available as a module, right?

So in the meantime, am I right that import std; is basically only realistic for new or small projects where the standard library header dependencies (both direct and transitive) can be fully tracked and migrated at the same time? Or is there a way to somehow migrate a project to import std; even if some of its dependencies have not yet migrated?

If I compile the following code with Microsoft (R) C/C++ Optimizing Compiler Version 19.37.32824 for x64 then I get C2572, which indeed suggests that transitive #includes cannot be mixed with import std;.

header.hpp

#include <iostream>

main.cpp

#include "header.hpp"
import std;
int main() {
  std::cout << "Hello, world!n";
}
C:Codeimport-std-test>cl /std:c++latest /EHsc /nologo /W4 /MTd "%VCToolsInstallDir%modulesstd.ixx" main.cpp
std.ixx
main.cpp
C:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.37.32822includextr1common(42): error C2572: 'std::enable_if': redefinition of default argument: parameter 1
C:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.37.32822includextr1common(43): note: see declaration of 'std::enable_if'
main.cpp(5): fatal error C1117: unrecoverable error importing module 'std': symbol 'byte' has already been defined
Generating Code...

2

Answers


  1. Chosen as BEST ANSWER

    Thanks to @BoP's comment it's now clear that mixing import std; and #include <header> is supposed to work but simply hasn't been implemented yet in MSVC (a fact that unfortunately is not mentioned in the tutorial). The linked talk doesn't mention when it will be available, but it sounds like Microsoft is actively working on it.

    So to answer the original question: no, import std; is not a realistic goal at the moment for most projects, but yes, it will be when MSVC fully implements the standard, which allows for mixing the two.


  2. Using import std; for C++ standard library headers is indeed a feature introduced in Visual Studio 2022 to improve compilation times and modularize the standard library. However, there are some important limitations and considerations to keep in mind, as you’ve pointed out.

    The limitation you mentioned is correct: you should not mix and match importing C++ standard library header files and named modules like import std; in the same file. This means that if you use import std; in a file, none of the non-standard library headers included in that file, either directly or transitively, should include standard library headers.

    The reason for this limitation is that once you import the std module, the entire C++ standard library becomes modularized and no longer relies on the traditional header inclusion mechanism. Mixing the two can lead to conflicts, as you’ve observed in your code example.

    Regarding the migration of existing projects to use import std;, it can indeed be challenging, especially if your project has dependencies on libraries like Boost that are not yet available as modules. In such cases, you may need to carefully track and update your project’s dependencies to ensure that none of them transitively include standard library headers. This can be a complex and time-consuming task.

    So, import std; may be more realistic for new or small projects where you have better control over the dependencies and can ensure that they also migrate to the module system. For larger and existing projects with complex dependencies, you may need to wait for libraries like Boost to become available as modules or consider alternative approaches to manage your project’s dependencies and compilation performance.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search