xleonch
xleonch

Reputation: 163

Can't use iostream as module in C++20 (Visual Studio)

I can't get this code running in the newest version of MSVC. This code example is from the book called "Beginning C++20, From Novice to Professional" by Ivor Horton and Peter Van Weert.

import <iostream>;

int main()
{
    int answer {42};
    std::cout << "The answer to life, universe, and everything is "
              << answer
              << std::endl;
    return 0;
}

I get this error:

could not find header unit for 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\include\iostream'

I am using Microsoft Visual Studio version 16.8.1, and have enabled these flags in project properties (according to the similar question Standard way of importing modules):

Should I use Clang or GCC instead?

Upvotes: 13

Views: 17512

Answers (5)

Evin
Evin

Reputation: 11

Some settings in Visual Studio have changed and support for C++ 20 has improved (checked with Visual Studio 2022 v 17.7.6 and 17.9.0).

Set the following in the project properties:

Property Language Settings

Property Advanced Settings

'Configuration Properties' -> 'C/C++' -> 'Language'

C++ Language Standard -> ISO C++20 Standard (/std:c++20) Enable Experimental C++ Standard Library Modules -> Yes (/experimental:module)

'Build ISO C++ 23 Standard Library Modules' isn't actually required for this example, but you may try enable that also

'Configuration Properties' -> 'C/C++' -> 'Advanced'

Compile As -> Compile as C++ Module Code (/interface )

Upvotes: 1

Alex
Alex

Reputation: 21

There appears to be fairly decent support for modules in MSVC now with and without CMake (presumably at this point clang as well). I can't exactly speak for clang, I've only just played around with MSVC and modules recently.

Unfortunately I've found that even though I've installed the required build tools there seems to be an issue where the MSVC compiler doesn't pick up on the fact there are system modules. Normally resulting in errors complaining that some expected module related file doesn't exist (which they most certainly should) or something to that effect. And then confusingly if I use the MSVC IDE I can import those same headers in other projects no problem, so why the IDE can figure this out I have to assume is due to extra configuration options I'm simply not aware of pointing it to the required files.

It seems you can potentially get the compiler to generate those files or whatever it is missing by using the typical #include <system_header> syntax first.

module;
#include <iostream>;
//I didn't test this, but my suspicion is that some functionality of the include has to be used in some portion of the export in order to generate the files missing.
//What I'm imagining is happening is that work is being done to
//treat the contents of the #include like a module, leaving behind files that can later be imported
export module some_module;

export {
}

And then, after successfully building (without errors), there's a chance replacing the syntax back with import may work. I've not had 100% success rate with this with other system headers. I know <vector>, <iostream> and <string> specifically can work. I wish this worked reliably so that in theory it'd be a relatively quick fix, unfortunately I think it's still a waiting game for modules to be reliably supported. Hopefully* this helps someone as frustrated as I was in the meantime.

Edit: I'm now slightly more confident my theory was correct, I just had MSVC complaining that import <string>; was a problem, I went and made a dummy module which included <string> and exported a function which used std::string which I then called in the main function and now after building suddenly import <string>; works as well.

Upvotes: 0

bogdyname
bogdyname

Reputation: 374

Try to do it like this:

import <iostream>;         // import declaration

Modules help divide large amounts of code into logical parts. Modules are orthogonal to namespaces.

Example:

File helloworld.cpp

export module helloworld;  // module declaration
import <iostream>;         // import declaration

export void hello() {      // export declaration
    std::cout << "Hello, World!\n";
}

File main.cpp

import helloworld;  // import declaration

int main() {
    hello();
}

Upvotes: -3

StudentRAF
StudentRAF

Reputation: 121

Using the Visual Studio 2019 non preview version:

  1. Create an empty C++ project

  2. Open project properties: Alt + Enter

  3. Go to Configuration PropertiesC/C++Language, and set the C++ Language Standard option to Preview - Features from the Latest C++

  4. In the same section, set Enable Experimental C++ Standard Library Modules to Yes (/experimental:module)

  5. Go to Configuration PropertiesC/C++Advanced and set the Compile As option to Compile as C++ Module Internal Partition (/internalPartition)

  6. Add header file to your project, which contains an import declaration for every standard library header you want to import. For example:

    #pragma once
    import <iostream>;
    import <array>;
    import <vector>;
    
  7. Recompile your project

  8. Done, now everything should work fine

Upvotes: 12

Glenarvan
Glenarvan

Reputation: 122

The authors stated in the example and solution files provided for download, that due to compilers' implementations of the C++20-standard the files might not work yet (see the book's page for details and corresponding GitHub repository).

Therefore they provide "no modules" examples which use the "#include" directive.

Upvotes: 4

Related Questions