默认比较运算符在 constexpr 时给出错误结果

Default comparison operator gives wrong result when constexpr

我正在测试 C++20 的新功能以自动生成比较运算符,我发现了一个奇怪的情况,即默认运算符似乎给出了错误的结果。

它只发生在 gcc 并且只有当运算符声明为 constexpr.

以下代码:

#include <iostream>

struct Foo
{
    int foo;
    constexpr bool operator==(const Foo&) const = default;
};

struct Bar : public Foo
{
    constexpr bool operator==(const Bar&) const = default;
};

int main()
{
    const Foo foo0{5};
    const Foo foo1{0};
    std::cout << "Foo: {" << foo0.foo << "} == {" << foo1.foo << "} => " << ((foo0 == foo1) ? "true" : "false") << std::endl;

    const Bar bar0{5};
    const Bar bar1{0};
    std::cout << "Bar: {" << bar0.foo << "} == {" << bar1.foo << "} => " << ((bar0 == bar1) ? "true" : "false") << std::endl;

    return 0;
}

当使用 gcc 编译时给出:

Foo: {5} == {0} => false
Bar: {5} == {0} => true

但是当用 clang 编译时给出:

Foo: {5} == {0} => false
Bar: {5} == {0} => false

编译器资源管理器link:https://godbolt.org/z/vbzo35an5

我假设这是 gcc 中的一个错误,但我不知道该语言的所有怪癖,所以我决定在报告之前先在这里问一下。

是的,编写的代码应该可以工作,所以这是一个 GCC 错误。默认值 operator== 应该对所有子对象进行相等比较,而不仅仅是成员子对象。

您可以从 the assembly output 中看出,GCC 11.1 为 Bar 生成的比较运算符代码与为没有子对象的结构生成的代码相同。