C++ spaceship operator `default` marked as deleted with `std::array` member

Hi Clang community,

This is my first post, sorry if this lands on the wrong location, and let me know if this is not the right place to ask such questions.

I am experiencing an issue with the spaceship operator <=> in C++20, and I would like to understand if this is a bug on the compiler or not, or if I am invoking the compiler wrong (although I initially have this issue directly in Xcode w. vanilla toolchain).

Here is the simple code I am trying to build:

#include <array>
#include <compare>

struct test
{
    std::array<std::int64_t, 1> coords;
    auto operator<=>(const test&) const = default;
};

void test_f() {
    test c1{1}, c2{2};
    auto t1 = (c1 <= c2);
}

This does not compile w. clang 14.x, 15.0.0, 15.0.1, 15.0.3 on macOS (x86_64 or m1) or on Ubuntu 20.04 (tested 15.0.3 only). The error is

test.cpp:7:15: warning: explicitly defaulted three-way comparison operator is implicitly deleted [-Wdefaulted-function-deleted]
                auto operator<=>(const test&) const = default;

....

test.cpp:12:24: error: object of type 'test' cannot be compared because its 'operator<=>' is implicitly deleted
                auto t1 = (c1 <= c2);
                              ^
test.cpp:7:15: note: explicitly defaulted function was implicitly deleted here
                auto operator<=>(const test&) const = default;
                     ^
test.cpp:6:34: note: defaulted 'operator<=>' is implicitly deleted because there is no viable three-way comparison function for member 'coords'
            std::array<std::int64_t, 1> coords;


The spaceship operator is available for std::array<std::int64_t, 1> and this code looks legit to me. It also seem to be working on godbolt.

For testing this, I am just downloading the available clang release archives and try to run clang as much as I can :slight_smile: :

  1. the command line I tried on Ubuntu is (from a freshly downloaded archive)

    clang++ -std=c++20 \
       -nostdinc++ \
       -isystem `pwd`/clang+llvm-15.0.2-x86_64-unknown-linux-gnu/include/c++/v1/ \
       -isystem `pwd`/clang+llvm-15.0.2-x86_64-unknown-linux-gnu/include/x86_64-unknown-linux-gnu/c++/v1/ \
       test.cpp
    
  2. on macOS, I am running this

    export SDKROOT=$(xcrun --show-sdk-path --sdk macosx)
    clang -std=c++20 -isysroot $SDKROOT/ test.cpp
    

The initial SO question is here.

Questions:

  1. is the error legit? is the code legit?
  2. am I invoking the compiler correctly?
  3. should I file a bug report?

Thank!

Compiler Explorer (“godbolt”) uses GCC’s libstdc++ even when building with clang, and it looks like libstdc++ defines an array::operator<=>(const array &, const array &) (see here).

LLVM’s libc++, which is what Xcode uses by default, does not appear to have one.

Looking at array.overview in the C++20 standard, it looks like there’s supposed to be one, but I might be missing something. In any case, I think it’s worth filing a bug against libc++.

1 Like

See libc++ Spaceship Operator Status (operator<=>) — libc++ documentation

array is marked as “In Progress”, though I’m not sure if there’s a patch for it out there.

1 Like

For what is worth, I forgot to mention that

std::array<std::int64_t, 1> coords{1};
auto t1 = (coords <= coords);

(ie. the std::array outside of the struct) works without any issue.

Yes, because std::array in libc++ still has all of operator== operator!= operator< operator> operator<= operator>=, it just doesn’t have the C++20 operator<=>, which should replace most of the earlier once implemented.

1 Like