You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含std::chrono的C++代码编译错误:_S_fractional_width问题求助

编译std::chrono相关代码时出现consteval函数未定义错误的原因及解决办法

问题描述

编译使用<std::chrono>库的C++日志模块时,标准库头文件报错:调用consteval函数std::chrono::hh_mm_ss::_S_fractional_width并非常量表达式,提示该函数未定义。项目采用CMake+Clang 14.0.6编译,切换GCC、执行apt更新升级后问题仍存在。

原因分析

  • 编译器与标准库兼容性冲突:错误信息显示使用的是GCC 13版本的libstdc++头文件,但编译器是Clang 14。GCC 13的libstdc++对std::chrono::hh_mm_ss的实现使用了C++20的consteval特性,而Clang 14对该版本libstdc++的consteval实现兼容性不足,导致编译期无法解析函数定义,触发错误。
  • 间接依赖触发问题:你的日志代码并未直接使用std::chrono::hh_mm_ss,但项目中其他依赖<chrono>的文件(如timer.cpp、benchmark_timer.hpp)可能间接实例化了该模板,从而触发错误。

解决办法

  • 强制使用Clang自带的libc++:修改CMakeLists.txt,添加编译选项指定使用Clang的标准库,避免与GCC的libstdc++冲突:
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lc++abi")
    
  • 升级Clang版本:Clang 15及以上版本对GCC 13的libstdc++兼容性更好,升级到Clang 15+可解决该问题。
  • 降级GCC标准库:若必须使用libstdc++,可安装GCC 12版本的标准库,通过环境变量或CMake指定使用该版本的头文件与库。
  • 排查间接依赖:检查timer.cpp或benchmark_timer.hpp中是否存在不必要的<chrono>模板使用,若能移除相关代码,可规避错误触发。

相关代码

log.cpp

#include "log.hpp"
#include <chrono>
#include <iomanip>
#include <iostream>
#include <utility>

#ifdef _WIN32
#include <windows.h>
#else
#define RESET "\033[0m"
#define COLOR_BEGIN(code) "\033[38;2;" << ((code >> 16) & 0xFF) << ";" << ((code >> 8) & 0xFF) << ";" << (code & 0xFF) << "m"
#endif

namespace Monolith
{
    namespace utils
    {
        void log::print_log(std::string &&message)
        {
            if (!m_enabled) return;
            auto now = std::chrono::system_clock::now();
            std::time_t time_point = std::chrono::system_clock::to_time_t(now);
            std::tm *timeinfo = std::localtime(&time_point);
            auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count() % 1000;

#ifdef _WIN32
            HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleTextAttribute(console, static_cast<WORD>(m_color));
#else
            std::cout << COLOR_BEGIN(m_color);
#endif
            std::cout << "[" << m_entity << "] {" << std::put_time(timeinfo, "%T") << ":" << std::setfill('0') << std::setw(3)
                      << milliseconds << "} " << message;

#ifdef _WIN32
            SetConsoleTextAttribute(console, static_cast<WORD>(0xFFFFFF));
#else
            std::cout << RESET << std::endl;
#endif
        }

        std::string format_args(const char *message, va_list args)
        {
            const size_t length = 1024;
            char *buffer = new char[length];
            vsnprintf(buffer, length, message, args);

            std::string result(buffer);

            delete[] buffer;

            return result;
        }

        log::log(std::string entity, unsigned int color) : m_entity(entity), m_color(color)
        {
        }

        void log::out(const char *message, ...)
        {
            va_list args;
            va_start(args, message);
            print_log(format_args(message, args));
            va_end(args);
        }

    } // namespace utils
} // namespace Monolith

log.hpp

#pragma once
#ifndef _LOG_HPP_
#define _LOG_HPP_

#include <iostream>
#include <stdarg.h>

namespace Monolith
{
    namespace utils
    {
        class log
        {
          public:
            log(std::string entity, unsigned int color);

            void out(const char *message, ...);

          private:
            void print_log(std::string &&message);

            bool m_enabled = true;
            std::string m_entity;
            unsigned int m_color;
        };

    } // namespace utils
} // namespace Monolith

#endif // !_LOG_HPP_

完整编译错误信息

┌──(recall㉿recall)-[/home/dev/monolith_engine]
└─$ ./cmake_build.sh debug
-- The C compiler identification is Clang 14.0.6
-- The CXX compiler identification is Clang 14.0.6
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Vulkan: /usr/lib/x86_64-linux-gnu/libvulkan.so (found version "1.3.250")  missing components: glslc glslangValidator
-- Configuring done (0.6s)
-- Generating done (0.0s)
-- Build files have been written to: /home/dev/monolith_engine/build
[ 20%] Building CXX object CMakeFiles/monolith.dir/src/utils/log.cpp.o
[ 40%] Building CXX object CMakeFiles/monolith.dir/src/main.cpp.o
[ 60%] Building CXX object CMakeFiles/monolith.dir/src/utils/timer.cpp.o
[ 80%] Building CXX object CMakeFiles/monolith.dir/src/mh_vulkan/renderer/mh_vk_renderer.cpp.o
In file included from /home/dev/monolith_engine/src/utils/log.cpp:2:
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: error: call to consteval function 'std::chrono::hh_mm_ss::_S_fractional_width' is not a constant expression
        static constexpr unsigned fractional_width = {_S_fractional_width()};
                                                      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: note: undefined function '_S_fractional_width' cannot be used in a constant expression
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2275:2: note: declared here
        _S_fractional_width()
        ^
In file included from /home/dev/monolith_engine/src/utils/timer.cpp:1:
In file included from /home/dev/monolith_engine/src/utils/timer.hpp:5:
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: error: call to consteval function 'std::chrono::hh_mm_ss::_S_fractional_width' is not a constant expression
        static constexpr unsigned fractional_width = {_S_fractional_width()};
                                                      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: note: undefined function '_S_fractional_width' cannot be used in a constant expression
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2275:2: note: declared here
        _S_fractional_width()
        ^
1 error generated.
make[2]: *** [CMakeFiles/monolith.dir/build.make:104: CMakeFiles/monolith.dir/src/utils/log.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
1 error generated.
make[2]: *** [CMakeFiles/monolith.dir/build.make:118: CMakeFiles/monolith.dir/src/utils/timer.cpp.o] Error 1
In file included from /home/dev/monolith_engine/src/mh_vulkan/renderer/mh_vk_renderer.cpp:1:
In file included from /home/dev/monolith_engine/src/mh_vulkan/renderer/mh_vk_renderer.hpp:6:
In file included from /home/dev/monolith_engine/src/mh_vulkan/renderer/../../core.hpp:31:
In file included from /home/dev/monolith_engine/src/mh_vulkan/renderer/../../utils/benchmark_timer.hpp:8:
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: error: call to consteval function 'std::chrono::hh_mm_ss::_S_fractional_width' is not a constant expression
        static constexpr unsigned fractional_width = {_S_fractional_width()};
                                                      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: note: undefined function '_S_fractional_width' cannot be used in a constant expression
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2275:2: note: declared here
        _S_fractional_width()
        ^
In file included from /home/dev/monolith_engine/src/main.cpp:1:
In file included from /home/dev/monolith_engine/src/core.hpp:31:
In file included from /home/dev/monolith_engine/src/utils/benchmark_timer.hpp:8:
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: error: call to consteval function 'std::chrono::hh_mm_ss::_S_fractional_width' is not a constant expression
        static constexpr unsigned fractional_width = {_S_fractional_width()};
                                                      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2320:48: note: undefined function '_S_fractional_width' cannot be used in a constant expression
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/chrono:2275:2: note: declared here
        _S_fractional_width()
        ^
1 error generated.
make[2]: *** [CMakeFiles/monolith.dir/build.make:90: CMakeFiles/monolith.dir/src/mh_vulkan/renderer/mh_vk_renderer.cpp.o] Error 1
1 error generated.
make[2]: *** [CMakeFiles/monolith.dir/build.make:76: CMakeFiles/monolith.dir/src/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/monolith.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

内容的提问来源于stack exchange,提问作者recall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:02:00