【问题标题】:Strange behavior in GCC: rvalue ref and lvalue ref are covariant return typesGCC 中的奇怪行为:rvalue ref 和 lvalue ref 是协变返回类型
【发布时间】:2021-06-16 06:31:05
【问题描述】:

我有这段小代码:

struct Res { };

struct A {
    virtual Res &&foo();
};

struct B : A {
    Res &foo() override;
};

它在 GCC 中编译,但不在 Clang 中:https://godbolt.org/z/65rffW

根据引用的标准语言here,左值引用不是右值引用的协变返回类型。

为什么 GCC 不发出错误?

【问题讨论】:

  • 这不是一个复杂的问题。假设这是不正确的,根据 C++ 标准,这只能是编译器错误或编译器扩展。我不知道有任何 gcc 对此效果的扩展。因此,逻辑规则得出结论,这一定是编译器错误?
  • @A.Hristov 表示该函数是为右值对象类型定义的,但此处不需要 - 即使使用普通函数也可以重现该错误。
  • @SergeyA 在代码中删除了 this 的右值引用,这是激发问题的真实代码的剩余部分。

标签: c++ gcc g++ language-lawyer


【解决方案1】:

这实际上是一份标准缺陷报告的主题,一个相当古老的报告:

  1. 协变函数和左值/右值引用 部分:11.7.3 [class.virtual] 状态:CD2 提交者:James Widman 日期:2009 年 9 月 1 日

[在 2010 年 3 月的会议上投票加入 WP。]

11.7.3 [class.virtual] 第 5 段要求协变返回类型既可以是指针也可以是引用,但它没有指定引用必须是左值引用或右值引用。这大概是一个疏忽。

提议的决议(2010 年 2 月):

将 11.7.3 [class.virtual] 第 5 段项目符号 1 更改如下:

...如果函数 D::f 覆盖函数 B::f,则函数的返回类型如果满足以下条件,则它们是协变的:

  • 都是类的指针,都是类的左值引用,或者都是右值类的引用106

...

来自http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#960


The code is undoubtedly ill-formed、Clang 和 MSVC(至少)确实解决了这个问题,而 GCC 没有。

我提交了一个错误报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99664


更新:

该错误已修复,test case here。将包含在 gcc 12 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 2018-06-26
    • 2013-10-14
    相关资源
    最近更新 更多