C++ Protocol Buffer: Temporary of non-literal type 'google::protobuf::internal::CallOnInitializedMutex <std::mutex>' in a constant expression

Viewed 1249

I'm using the protoc-3.18.0-win32 version from here. After successfully compiling the .proto files, I get the following error in my QtCreator 5 (C++11) program:

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

where the erroneous lines of code are:

// 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
2 Answers

I hit the same issue when trying to use protobuf version higher than 3.15.0 with gcc 7.3 and c++17. This turned out to be a gcc bug, see more in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82461.

After looking into the protobuf generated code, what i find is in version after 3.15, protobuf generated code container pervasive 'constexpr' which trigger the gcc bug.

Possible solution:

  1. use higher version of gcc, the bug is fixed in 7.4 (preferred)
  2. use '-std=c++14' instead of '-std=c++17', this works for me
  3. use protobuf older than 3.15, 3.13 and 3.14 works for me.

In my case it was enough: Go to your opencv folder, find the file \opencv\sources\3rdparty\protobuf\src\google\protobuf\stubs\mutex.h and delete the line after the first else at the WrappedMutex class,

class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
 audience:
#if defined(__QNX__)
  constexpr WrappedMutex() = default;
#else
  constexpr WrappedMutex() {} // **Delete this line**
#endif
Related