Visitar URL original
cannot compile c++ generated code · Issue #8484 · protocolbuffers/protobuf · GitHub
Skip to content

cannot compile c++ generated code #8484

Closed

Description

@Eddie-cz

Version: 3.15.8
Language: C++
Windows 10, MSVC 16.9.3 with clang-cl compiler (LLVM 11.1)

Message definition:
syntax = "proto3";
message StringMsg
{
string value = 1;
}

Compilation of generated pb.cc fails for this message with "error : variable does not have a constant initializer".
Compiles with repeated modifier.

Variable is:
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT StringMsgDefaultTypeInternal StringMsg_default_instance;

Activity

  1. TeBoring commented on Apr 22, 2021

    @TeBoring
    Contributor

    Do you see if there is a constexpr constructor for StringMsgDefaultTypeInternal in .pb.cc?

  2. TeBoring commented on Apr 22, 2021

    @TeBoring
    Contributor

    Could you also paste the full error log?

  3. Eddie-cz commented on Apr 22, 2021

    @Eddie-cz
    ContributorAuthor

    There is constexpr constructor, code compiles fine with msvc compiler, only clang-cl (both 11.1 or 12.0) thinks this message variable doesn't satisfy constinit restrictions introduced by PROTOBUF_CONSTINIT (guess it has problems with string type).
    Should I put repeated modifier for that string param, or manualy remove PROTOBUF_CONSTINIT from pb.cc, it compiles fine.
    Log:
    etherCATMessages.pb.cc(114,79): error : variable does not have a constant initializer
    etherCATMessages.pb.cc(114,31): message : required by 'require_constant_initialization' attribute here
    protobuf\3.15.8\include\google/protobuf/port_def.inc(571,30): message : expanded from macro 'PROTOBUF_CONSTINIT'

  4. TeBoring commented on Apr 23, 2021

    @TeBoring
    Contributor

    https://godbolt.org/z/75rfhqY4E
    I cannot reproduce it in the godbolt. Could you help advice a reproduce?

  5. TeBoring commented on Apr 23, 2021

    @TeBoring
    Contributor
  6. Eddie-cz commented on Apr 26, 2021

    @Eddie-cz
    ContributorAuthor

    Issue is isolated to
    PROTOBUF_CONSTINIT google::protobuf::internal::ArenaStringPtr sptr(&google::protobuf::internal::fixed_address_empty_string);
    Same error as described above. To reproduce, you must define your ExplicitlyConstructed<std::string> empty_string variable; in different compilation unit, in this case in different dll, same as it's for protobuf variables. When I test your code in one compilation unit, it's ok, problem is with protobuf dll usage.

  7. ngg commented on May 26, 2021

    @ngg
    Contributor

    We ran into the same problem.
    If I try to compile libprotobuf into a dll, and compile the protoc executable that uses this dll with clang-cl, then I get an error like this from plugin.pb.cc:

    error: variable does not have a constant initializer
    PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT VersionDefaultTypeInternal _Version_default_instance_;
    

    I tried using protobuf 3.15.2 and 3.17.1

  8. sbenzaquen commented on May 26, 2021

    @sbenzaquen
    Member

    It seems to be an interaction between __declspec(dllimport) and constant initialization.
    I can't test with clang-cl, so my tests below are with MSVC.

    If I write:

    __declspec(dllimport) extern int x;
    auto& p = x;
    

    then p is dynamically initialized (at least in the latest MSVC)
    If the symbol is not dllimport, then p is constant initialized as expected.

    I think what's happening is that clang is following this behavior but since it also supports the [[clang::require_constant_initialization]] attribute it is failing there because it is indeed not constant initialized.

    We might want to disable the attribute in clang-for-windows.
    The attribute is not required for correctness. It is there mostly to make sure we really are constant initialized in the platforms that support it for code size efficiency.

  9. ngg commented on May 26, 2021

    @ngg
    Contributor

    I also checked that if I compile with clang in C++20 mode, then constinit is used, and the same error still appears.
    I did not check what happens with MSVC, but if C++20 is enabled (using /std:c++latest) and constinit is used then I think it wouldn't compile either. (clang seems to be right, this is not supposed to work as constantly initialized on Windows)

  10. sbenzaquen commented on May 26, 2021

    @sbenzaquen
    Member

    I don't know about that.

    This works fine:

    __declspec(dllimport) extern int x;
    constexpr auto& p = x;
    

    So it can do constant initialization for it, but it just chooses not to when constexpr is not there.
    tbh, I don't know enough about the semantics of dllexport/dllimport.

  11. kelteseth commented on Jun 29, 2021

    @kelteseth

    I can confirm this issue with clang 12 on Windows.

    manualy remove PROTOBUF_CONSTINIT from pb.cc, it compiles fine.

    This fixes the problem for me

  12. mmurrian commented on Sep 10, 2021

    @mmurrian

    We might want to disable the attribute in clang-for-windows.

    That was my solution. I changed line 571 of port_def.inc to:
    #if !defined(_MSC_VER) && __has_cpp_attribute(clang::require_constant_initialization)

    Same problem on Visual Studio 2019, clang-cl, Windows.

  13. Eddie-cz commented on Sep 16, 2021

    @Eddie-cz
    ContributorAuthor

    Will make pull request as suggested by mmurrian, kinda suprised multiple versions were released in last 6 month and nobody was concerned with fact that library is producing not compilable code under msvc clang-cl environment.

  14. acozzette commented on Sep 22, 2021

    @acozzette
    Collaborator

    This should be fixed now with #8993.

  15. martenrichter commented on Jul 9, 2022

    @martenrichter

    I am currently trying to build libquiche for windows with a cmake build and clang as compiler.
    The patch seems to be removed from the repository.
    And I am getting:
    ....webtransport\third_party\quiche\quiche\quic\core\proto\cached_network_parameters.pb.cc(40,127): error : variable does not have a constant initializer [...webtransport\build\gquiche.vcxproj] ....third_party\quiche\quiche\quic\core\proto\cached_network_parameters.pb.cc(40,31): message : required by 'require_constant_initialization' attribute here [...webtransport\build\gquiche.vcxproj] C:\vcpkg\installed\x64-windows\include\google/protobuf/port_def.inc(651,30): message : expanded from macro 'PROTOBUF_CONSTINIT' [...webtransport\build\gquiche.vcxproj]
    If I patch port_def.inc analog to the previous patch:
    #elif !defined(_MSC_VER) && __has_cpp_attribute(clang::require_constant_initialization) && \ ((defined(__APPLE__) && __clang_major__ >= 13) || \ (!defined(__APPLE__) && __clang_major__ >= 12))
    it is fixed again.
    Can you consider adding this check again?

  16. Eddie-cz commented on Jul 9, 2022

    @Eddie-cz
    ContributorAuthor

    Yey, this is getting ridiculous more and more. I made another pull request, it is not approved yet. #10232

  17. martenrichter commented on Jul 9, 2022

    @martenrichter

    @Eddie-cz: Thanks for making the new PR, it much better then mine, and yes using protocol buffers on windows is pretty complicated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions