getml / reflect-cpp

A C++20 library for fast serialization, deserialization and validation using reflection. Supports JSON, BSON, CBOR, flexbuffers, msgpack, TOML, XML, YAML / msgpack.org[C++20]
https://getml.github.io/reflect-cpp/
MIT License
821 stars 65 forks source link

Compilation error for clang 16.0.6 on MacOs 14.2.1 #48

Closed melton1968 closed 2 months ago

melton1968 commented 6 months ago

I get the following error when trying to build the tests using clang 16.0.6 on MacOs 14.2.1. main, v0.6.0, v0.5.0, v0.4.0 and v0.3.0 all exhibit the same issue.

Am I missing something in the configuration or compiler? The details of the clang invocation are included below.

In file included from reflect-cpp/tests/json/test_all_of.cpp:4:
In file included from reflect-cpp/include/rfl/json.hpp:4:
In file included from reflect-cpp/include/rfl/json/Parser.hpp:6:
In file included from reflect-cpp/include/rfl/json/../parsing/Parser.hpp:8:
In file included from reflect-cpp/include/rfl/json/../parsing/Parser_default.hpp:10:
In file included from reflect-cpp/include/rfl/json/../parsing/../internal/enums/StringConverter.hpp:11:
reflect-cpp/include/rfl/json/../parsing/../internal/enums/get_enum_names.hpp:136:51: error: 
      non-type template argument is not a constant expression
  using EmptyNames = Names<EnumType, rfl::Literal<"">, 0>;
/opt/local/bin/clang++-mp-16  -Ireflect-cpp/include -std=c++20 -Wall -Wno-sign-compare -Wno-missing-braces -Wno-psabi -pthread -fno-strict-aliasing -fwrapv -O2 -ftemplate-backtrace-limit=0 -fsanitize=undefined -O3 -DNDEBUG -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk -std=gnu++20 -MD -MT tests/json/CMakeFiles/reflect-cpp-json-tests.dir/test_anonymous_fields.cpp.o -MF CMakeFiles/reflect-cpp-json-tests.dir/test_anonymous_fields.cpp.o.d -o CMakeFiles/reflect-cpp-json-tests.dir/test_anonymous_fields.cpp.o -c reflect-cpp/tests/json/test_anonymous_fields.cpp
melton1968 commented 6 months ago

I've narrowed the issue down to the following. The expression StringLiteral("") is not constexpr on MacOs. The error message indicates that a subobject is not being initialized.

#include <algorithm>
#include <array>
#include <string>
#include <string_view>
#include <iostream>

template <size_t N>
struct StringLiteral {

   constexpr StringLiteral(const char (&_str)[N]) {
    std::copy_n(_str, N - 1, std::data(arr_));
  }

  std::array<char, N - 1> arr_;
};

int main(int argc, char **argv) {
    constexpr auto a = StringLiteral("abc");
    constexpr auto b = StringLiteral("");   // This line is an error on MacOs because the value is not constexpr.
}
$ clang-mp-16 -std=c++20 ../src/tools/test.cpp 
../src/tools/test.cpp:44:20: error: constexpr variable 'b' must be
      initialized by a constant expression
    constexpr auto b = StringLiteral("");
                   ^   ~~~~~~~~~~~~~~~~~
../src/tools/test.cpp:44:20: note: subobject of type '_CharType'
      (aka 'char') is not initialized
/opt/local/libexec/llvm-16/bin/../include/c++/v1/array:272:46: note: 
      subobject declared here
    _ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)];
                                             ^
1 error generated.
melton1968 commented 6 months ago

Adding default initialization to the _arr member fixes the issue.

I am unsure if this is a feature or bug for the clang/Darwin platform? Is it related to the arm architecture? A latent bug? I have no way to test for x86/Darwin or arm/Ubuntu.

template <size_t N>
struct StringLiteral {

   constexpr StringLiteral(const char (&_str)[N]) {
    std::copy_n(_str, N - 1, std::data(arr_));
  }

  std::array<char, N - 1> arr_{};
};
liuzicheng1987 commented 6 months ago

Interesting, thank you so much for figuring this out. I will merge the PR later.

liuzicheng1987 commented 6 months ago

I think the issue may be MacOS vs Linux. My own private computer is a Mac with Apple Silicon chips as well, but I always use a Linux VM for development (so that would be Ubuntu/arm). I compile this using Clang as well as GCC on my computer, so it is very unlikely to be related to the arm architecture. The GitHub Actions pipeline we have set up also tests on Clang, but on Linux as well. We have naively assumed that testing on Clang is fine, but it appears we have to find a way to specifically test on clang/macOS.

ChemiCalChems commented 6 months ago

I'm still quite confused as to how this can even happen. Isn't clang supposed to have the same front-end on different platforms?

liuzicheng1987 commented 6 months ago

@melton1968 , I have merged your PR. But I want to keep the issue open, because I want to figure out what exactly has caused this. I agree with @ChemiCalChems that this is all still a bit of a mystery.

liuzicheng1987 commented 2 months ago

I have added two different runners for macOS clang to the automated testing pipeline. I think if the issue somehow reappears we will very likely catch it. So I think it is now time to close this issue.