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

aarch64架构GCC编译时宏传入的右值std::string_view非常量表达式报错问题

问题根因

报错并非aarch64版本GCC的bug,是代码中参数声明不合理导致编译期格式检查失败:

  1. 你封装的Warn成员函数使用了无意义的const右值引用接收格式字符串:const std::string_view &&message。字符串字面量隐式转换得到的std::string_view临时对象绑定到该参数后,变量message会失去编译期常量属性。你使用的spdlog版本依赖fmt库的编译期格式字符串校验,要求格式参数必须是常量表达式,因此触发报错。
  2. x86与aarch64表现不一致是因为不同架构下GCC的常量传播优化策略、spdlog/fmt的默认编译选项判定存在差异,并非架构侧的编译器缺陷。
  3. 额外问题:构造函数中const spdlog::level::level_enum &&logLevel的const右值引用声明也没有实际意义,会限制参数传入方式。
解决方案

1. 修正Warn函数参数声明

两种改法可选:

改法A 兼容现有逻辑,改动最小

将const右值引用改为普通const左值引用即可:

template <typename... Args>
void Warn(const std::string_view &message, Args &&...args) const
{
    _logger->warn(message, std::forward<Args>(args)...);
}

改法B 保留编译期格式检查,性能更优

直接用模板参数接收格式字符串,保留编译期常量属性,能提前发现格式不匹配问题:

template <typename FormatStr, typename... Args>
void Warn(FormatStr &&message, Args &&...args) const
{
    _logger->warn(std::forward<FormatStr>(message), std::forward<Args>(args)...);
}

2. 修正其他不合理的右值引用声明

构造函数的日志级别参数去掉多余的右值引用:

SpdLogLogger(const char *loggerName, const char *filename,
             spdlog::level::level_enum logLevel = spdlog::level::info)

3. (可选)优化宏定义

原LOG_WARN宏没有用do-while(0)包裹,在复杂if嵌套场景下可能出现语法问题,建议修改为:

#define LOG_WARN(logger, message, ...) do { if (logger) { logger->Warn(message, __VA_ARGS__); } } while(0)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:15:05