microsoft / STL

MSVC's implementation of the C++ Standard Library.
Other
10.07k stars 1.49k forks source link

Module STD: Redefinition Errors When Using import std Along With Other STL Includes #4822

Closed JamesDAT closed 2 months ago

JamesDAT commented 3 months ago

Describe the bug

When mixing import std; with other include types for the standard library, redefinition errors are thrown. When import std is placed after other standard library includes, a range of different redefinition errors are thrown, such as C2011 or C2572. When import std, is placed before other standard library includes, I get undeclared identifier errors. Although having these includes like the following code example would be strange, when including or importing large header files, which could have lots of different standard library includes, import std can no longer be used, seemingly in the entire project.

Command-line test case

Main.cpp

#include <vector>
import std;

int main() {
    std::vector<int> ints = { 1,2,3,4,5 };
    std::print("{}", *ints.begin());
}

This will give the following output:

1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\vector(435,49): error C2572: 'std::vector': redefinition of default argument: parameter 1
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\xmemory(538,51): error C2572: 'std::allocation_result': redefinition of default argument: parameter 1
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\xutility(7113,65): error C2572: 'std::iterator': redefinition of default argument: parameter 1
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\xutility(7113,93): error C2572: 'std::iterator': redefinition of default argument: parameter 2
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\xutility(7114,24): error C2572: 'std::iterator': redefinition of default argument: parameter 3
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\xutility(775,9): error C2373: 'std::input_iterator': redefinition; different type modifiers
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\vector(606,1): fatal  error C1907: unable to recover from previous error(s); stopping compilation
1>INTERNAL COMPILER ERROR in 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\bin\HostX64\x64\CL.exe'

Various combinations of #include and import as well as swapping the include order all gives errors. I also had the issue where an independent module would cause the errors without import std.

ECS.ixx

export module ECS;
import <entt/entt.hpp>; // causes redefinition errors

namespace Nova {
    export class ECS {
    public:

    private:
        entt::registry m_Registry;
    };
}

i have fixed the issue by removing all instances of import std; from the project, adding any back gives me the redefinition errors again. entt.hpp only uses regular #include <> for including standard lib

Expected behavior

Do not cause redefinition errors when using import std along with other includes. It should act the same as doing

import <vector>;
import <vector>;

STL version

Microsoft Visual Studio Community 2022
Version 17.10.3
jovibor commented 2 months ago

This code compiles and works perfectly fine in my 17.10.3:

#include <vector>
import std;

int main() {
    std::vector<int> ints = { 1, 2, 3, 4, 5 };
    std::print("{}", *ints.begin());
}

Prints 1.

JamesDAT commented 2 months ago

This code compiles and works perfectly fine in my 17.10.3:

#include <vector>
import std;

int main() {
    std::vector<int> ints = { 1, 2, 3, 4, 5 };
    std::print("{}", *ints.begin());
}

Prints 1.

Strange, using this exact code in a blank project, using /std:c++latest, gives me errors. Is there anything else that could be causing it, or is there any other information i could give to help diagnose the issue?

jovibor commented 2 months ago

Make sure you set this option to yes: image

All the others are pretty standard.

JamesDAT commented 2 months ago

I did have that set to no, but switching to yes unfortunately still gives me the same errors.

StephanTLavavej commented 2 months ago

@JamesDAT It looks like you're compiling with 17.8, which predated the change that allowed include-before-import to work. Observe this part of your compiler errors:

1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include\vector(435,49): error C2572: 'std::vector': redefinition of default argument: parameter 1

14.38.33130 is a 17.8 toolset version (see our _MSVC_STL_UPDATE wiki page for a decoder table for _MSC_VER; the compiler versions are 19.xx and the IDE versions are 14.xx because the C++ compiler predates the "Visual" in Visual C++, our versioning scheme is admittedly a dumpster fire orbiting a supernova :wastebasket: :fire: :star:).

The simplest way to absolutely verify that you're using a 17.10 toolset (with the fix) or later is to add this to your code:

#if _MSC_VER < 1940
#error This MSVC version is older than 19.40, aka VS 2022 17.10
#endif

See https://godbolt.org/z/5jjeedvKc for a demonstration.

I'm not sure exactly how you're picking up the 17.8 toolset, but can you try again with the 17.10 toolset?

JamesDAT commented 2 months ago

Switching over the 17.10 has solved the problem. Although looking at my components, i had build tools (latest) and build tools (17.8) installed, yet 17.8 still took precedence. Even when i installed 17.10, visual studio still continued to use 17.8 until i uninstalled it. Anyway thanks for the help 👍

StephanTLavavej commented 2 months ago

Great, thanks! Yeah, I believe that's a known bug (something involving VS's "props" files, where the latest toolset isn't automatically used), unfortunately.