默认比较运算符在 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
生成的比较运算符代码与为没有子对象的结构生成的代码相同。
我正在测试 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
生成的比较运算符代码与为没有子对象的结构生成的代码相同。