C++ 协议缓冲区:常量表达式中的临时非文字类型 'google::protobuf::internal::CallOnInitializedMutex <std::mutex>'

Posted

技术标签:

【中文标题】C++ 协议缓冲区:常量表达式中的临时非文字类型 \'google::protobuf::internal::CallOnInitializedMutex <std::mutex>\'【英文标题】:C++ Protocol Buffer: Temporary of non-literal type 'google::protobuf::internal::CallOnInitializedMutex <std::mutex>' in a constant expressionC++ 协议缓冲区:常量表达式中的临时非文字类型 'google::protobuf::internal::CallOnInitializedMutex <std::mutex>' 【发布时间】:2021-11-12 20:30:26 【问题描述】:

我正在使用来自here 的 protoc-3.18.0-win32 版本。成功编译 .proto 文件后,我的 QtCreator 5 (C++11) 程序中出现以下错误:

C:\Users\MyName\MyProject\lib\include\google\protobuf\stubs\mutex.h:124: error: temporary of non-literal type 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' in a constant expression
In file included from lib\include/google/protobuf/descriptor.h:66:0,
                 from lib\include/google/protobuf/message.h:121,
                 from lib\include/google/protobuf/generated_message_bases.h:42,
                 from src/protodata/myfile.pb.h:26,
                 from src/myfile/myfile.h:12,
                 from src\myclass/myclass.h:8,
                 from src\mywidget.cpp:2:
lib\include/google/protobuf/stubs/mutex.h: In constructor 'constexpr google::protobuf::internal::WrappedMutex::WrappedMutex()':
lib\include/google/protobuf/stubs/mutex.h:124:29: error: temporary of non-literal type 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' in a constant expression
   constexpr WrappedMutex() 
                             ^
lib\include/google/protobuf/stubs/mutex.h:98:7: note: 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' is not literal because:
 class CallOnceInitializedMutex 
       ^~~~~~~~~~~~~~~~~~~~~~~~
lib\include/google/protobuf/stubs/mutex.h:98:7: note:   'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' has a non-trivial destructor

错误的代码行在哪里:

// Mutex is a natural type to wrap. As both google and other organization have
// specialized mutexes. gRPC also provides an injection mechanism for custom
// mutexes.
class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex 
 public:
#if defined(__QNX__)
  constexpr WrappedMutex() = default;
#else
  constexpr WrappedMutex()  // <--- Error points here
#endif

【问题讨论】:

【参考方案1】:

在尝试将高于 3.15.0 的 protobuf 版本与 gcc 7.3 和 c++17 一起使用时,我遇到了同样的问题。这原来是一个 gcc 错误,请参阅 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82461 中的更多内容。

查看 protobuf 生成的代码后,我发现在 3.15 之后的版本中,protobuf 生成的代码容器普遍存在“constexpr”,它触发了 gcc 错误。

可能的解决方案:

    使用更高版本的 gcc,7.4 修复了该错误(首选) 使用 '-std=c++14' 而不是 '-std=c++17',这对我有用 使用早于 3.15、3.13 和 3.14 的 protobuf 对我有用。

【讨论】:

以上是关于C++ 协议缓冲区:常量表达式中的临时非文字类型 'google::protobuf::internal::CallOnInitializedMutex <std::mutex>'的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式中的捕获和非捕获

C++ 中的每个表达式是不是都具有非指针类型,如非引用类型

模板的简单介绍与使用

现代C++笔记

C++标准库函数 end 的实现原理(非类型模板参数)

二进制表达式中的 GCC 常量临时