protocolbuffers / protobuf

Protocol Buffers - Google's data interchange format
http://protobuf.dev
Other
64.1k stars 15.31k forks source link

C++ generator `proto_h` feature does not compile #16863

Open nikhilkalige opened 2 weeks ago

nikhilkalige commented 2 weeks ago

I have been unable to compile c++ code generated by passing --cpp_out=proto_h to the compiler. I tried compiling just the generated pb.cc file and I get the following errors on v24.4.

gcc -I/nix/store/wbg3pd2jb1p9xc8208bs7hl1s55ya3ic-protobuf-24.4/include  -I/nix/store/pd328i3rxal7kr0j0sq2kf2hmyk2ss5d-abseil-cpp-20240116.1/include -std=c++17 -c mymsg.pb.cc -o mymsg.o

Data.proto.h:152:7: note: forward declaration of ‘class MyData’
  152 | class MyData;
      |       ^~~~~~~~~~~~
In file included from /usr/include/c++/11/bits/move.h:57,
                 from /usr/include/c++/11/bits/stl_pair.h:59,
                 from /usr/include/c++/11/bits/stl_algobase.h:64,
                 from /usr/include/c++/11/bits/char_traits.h:39,
                 from /usr/include/c++/11/string:40,
                 from MyMsg.proto.h:8,
                 from MyMsg.pb.cc:4:
/usr/include/c++/11/type_traits:1341:52: error: static assertion failed: template argument must be a complete class or an unbounded array
 1341 |       static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/11/type_traits:1341:52: note: ‘std::__is_complete_or_unbounded<std::__type_identity<MyData> >((std::__type_identity<MyData>{}, std::__type_identity<MyData>()))’ evaluates to false
In file included from MyMsg.proto.h:25,
                 from MyMsg.pb.cc:4:
/nix/store/wbg3pd2jb1p9xc8208bs7hl1s55ya3ic-protobuf-24.4/include/google/protobuf/arena.h: In instantiation of ‘class google::protobuf::Arena::InternalHelper<MyData>’:
/nix/store/wbg3pd2jb1p9xc8208bs7hl1s55ya3ic-protobuf-24.4/include/google/protobuf/arena.h:527:10:   required from ‘struct google::protobuf::Arena::is_arena_constructable<MyData>’
/nix/store/wbg3pd2jb1p9xc8208bs7hl1s55ya3ic-protobuf-24.4/include/google/protobuf/arena.h:603:43:   required from ‘static T* google::protobuf::Arena::CreateMaybeMessage(google::protobuf::Arena*, Args&& ...) [with T = MyData; Args = {}]’
/nix/store/wbg3pd2jb1p9xc8208bs7hl1s55ya3ic-protobuf-24.4/include/google/protobuf/repeated_ptr_field.h:805:43:   required from ‘static GenericType* google::protobuf::internal::GenericTypeHandler<Type>::New(google::protobuf::Arena*) [with GenericType = MyData]’
/nix/store/wbg3pd2jb1p9xc8208bs7hl1s55ya3ic-protobuf-24.4/include/google/protobuf/repeated_ptr_field.h:812:15:   required from ‘static GenericType* google::protobuf::internal::GenericTypeHandler<Type>::NewFromPrototype(const GenericType*, google::protobuf::Arena*) [with GenericType = MyData]’
/nix/store/wbg3pd2jb1p9xc8208bs7hl1s55ya3ic-protobuf-24.4/include/google/protobuf/repeated_ptr_field.h:216:38:   required from ‘typename TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add(const typename TypeHandler::Type*) [with TypeHandler = google::protobuf::RepeatedPtrField<MyData>::TypeHandler; typename TypeHandler::Type = MyData]’
/nix/store/wbg3pd2jb1p9xc8208bs7hl1s55ya3ic-protobuf-24.4/include/google/protobuf/repeated_ptr_field.h:1380:48:   required from ‘Element* google::protobuf::RepeatedPtrField<T>::Add() [with Element = MyData]’
/nix/store/wbg3pd2jb1p9xc8208bs7hl1s55ya3ic-protobuf-24.4/include/google/protobuf/arena.h:472:54: error: ‘value’ is not a member of ‘std::is_trivially_destructible<MyData>’
  472 |                   std::is_trivially_destructible<T>::value>
      |                                                      ^~~~~

I tried updating it to v26.1, even with that version I get different errors. Is there any documentation or examples on how to get this working.

Thank you

What version of protobuf and what language are you using? Version: 24.4 Language: C++

What operating system (Linux, Windows, ...) and version? Linux

What runtime / compiler are you using (e.g., python version or gcc version) gcc 11.4.0

sbenzaquen commented 2 weeks ago

The .proto.h codegen does not give transitive declarations. You have to include each file that you use. Eg when you do foo.bar() you have to include the .proto.h for the type of foo and the .proto.h for the type returned by bar().

This is opposed to .pb.h that does transitive inclusions and you can do a single include for a whole dependency tree.

nikhilkalige commented 2 weeks ago

@sbenzaquen That does make sense, but should you not be able compile at-least the generated .pb.cc files without any change?