C++20中constexpr修饰的默认==运算符在GCC下返回错误结果
GCC constexpr 默认生成比较运算符的继承类错误
你碰到的这个问题确实是GCC的已知bug,和C++20中constexpr默认比较运算符的继承处理逻辑直接相关。
问题根源
当基类Foo声明了constexpr的默认==运算符,派生类Bar也跟着声明自己的constexpr默认==时,GCC没有正确生成派生类的比较逻辑——它完全忽略了基类子对象的比较,直接返回true,这明显违反了C++标准的规定。
按照C++20标准,默认生成的相等运算符会递归比较所有基类子对象和非静态成员变量。对于Bar这种没有额外成员的派生类,它的默认==应该等价于比较基类Foo的foo成员,结果理应和Foo的比较一致。
复现代码
你的测试代码已经完美复现了问题:
#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
后续建议
这是GCC在处理constexpr默认比较运算符继承场景时的实现缺陷,不是C++标准本身的问题。你可以放心提交GCC的bug报告,这个案例非常清晰,能帮助开发者快速定位问题。另外,也可以尝试升级到较新的GCC版本,看看是否已经修复了这个bug。
内容的提问来源于stack exchange,提问作者Piotr Siupa
相关产品推荐
相关产品推荐

