代码之家  ›  专栏  ›  技术社区  ›  Todd Burch

将SpdLog与模块/C++20一起使用会导致内部编译器错误(MSVC 2022)

  •  0
  • Todd Burch  · 技术社区  · 3 年前

    我只想封装标题 spdlog C++20模块中的日志记录库,该库将spdlog库保留在模块内部。Logger类是Meyers风格的单例,我认为它很简单,但给我带来了很多麻烦。这是我试图解决的简化版本(请注意,虽然我专业地使用C#进行开发,但我对C++还是很陌生)。

    我的 Logger.cppm 模块如下所示:

    module;
    
    #pragma once
    
    #include "spdlog/spdlog.h"
    #include "spdlog/sinks/stdout_color_sinks.h"
    
    export module Logger;
    
    import <memory>;
    
    export namespace ThreeSpace
    {
        class Logger final
        {
        public:
            Logger(const Logger&) = delete;
            Logger& operator=(const Logger&) = delete;
    
            static void Trace() { Get()->trace("Test"); }
    
        private:
            std::shared_ptr<spdlog::logger> s_logger;
    
            Logger() : s_logger(spdlog::stdout_color_mt("Logger Name"))
            {}
    
            ~Logger() = default;
    
            static std::shared_ptr<spdlog::logger>& Get()
            {
                static Logger instance;
                return instance.s_logger;
            }
        };  
    }
    

    这是在我的Visual Studio 2022解决方案中一个名为“Core”的项目中。该项目成功地构建为一个静态库,没有任何问题。

    然而,在引用“Core”项目的应用程序项目(可执行文件)中,我有一个简单的“Main.cppm”模块,它试图使用记录器:

    export module Main;
    
    import Logger;
    
    export int main()
    {
        ThreeSpace::Logger::Trace();
    }
    

    此项目未成功生成。我在生成日志中得到以下内容:

    Build started...
    1>------ Build started: Project: ThreeSpace, Configuration: Debug x64 ------
    1>Scanning sources for module dependencies...
    1>Scanning sources for module dependencies...
    1>Main.cppm
    1>Compiling...
    1>Main.cppm
    1>C:\Dev\ThreeSpace\ThreeSpace\src\Main.cppm(9): fatal  error C1001: Internal compiler error.
    1>(compiler file 'msc1.cpp', line 1589)
    1> To work around this problem, try simplifying or changing the program near the locations listed above.
    1>If possible please provide a repro here: https://developercommunity.visualstudio.com
    1>Please choose the Technical Support command on the Visual C++
    1> Help menu, or open the Technical Support help file for more information
    1>INTERNAL COMPILER ERROR in 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\bin\HostX64\x64\CL.exe'
    1>    Please choose the Technical Support command on the Visual C++
    1>    Help menu, or open the Technical Support help file for more information
    1>Done building project "ThreeSpace.vcxproj" -- FAILED.
    ========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========
    ========== Build started at 10:21 PM and took 02.443 seconds ==========
    

    如果我注释掉对ThreeSpace::Logger::Trace();的调用;,该应用程序运行良好。

    你知道我做错了什么吗?现在是2023年,C++20代码出现这样一个通用的“内部编译器错误”真是令人沮丧!

    0 回复  |  直到 3 年前
        1
  •  1
  •   Todd Burch    3 年前

    好吧,经过随机实验,我修复了它。我所要做的就是把Trace()定义变成一个声明,然后在类之外定义方法,如下所示:

    module;
    
    #include "spdlog/spdlog.h"
    #include "spdlog/sinks/stdout_color_sinks.h"
    
    export module Logger;
    
    import <memory>;
    
    export namespace ThreeSpace
    {
        class Logger final
        {
        public:
            static void Trace();  //This is now just a declaration.
            Logger(const Logger&) = delete;
            Logger& operator=(const Logger&) = delete;
    
        private:
            std::shared_ptr<spdlog::logger> s_logger;
    
            Logger() :
                s_logger(spdlog::stdout_color_mt("Logger Name"))
            { }
    
            ~Logger() = default;
    
            static std::shared_ptr<spdlog::logger>& Get()
            {
                static Logger instance;
                return instance.s_logger;
            }
        };  
    
        //The definition of the method is now outside the class.
        void Logger::Trace() { Get()->trace("Test"); }
    }
    

    我不知道为什么这能解决问题,但它确实解决了!