在不合格的呼叫上,Clang和GCC上的错误

Bug on both clang and gcc on unqualified call

本文关键字:GCC 错误 Clang 呼叫 不合格      更新时间:2023-10-16

标准清单:

6.4.1

在[basic..lookup.argdep]中介绍了用作函数调用后的未合格名称的查找。 [注意:为了确定(解析过程(表达式是否是函数调用的后置缩短表达,请使用通常的名称查找规则。 在某些情况下,名称姓氏为<即使名称查找未找到模板名称,也将其视为模板名称(请参阅[temp.names](。 例如,

namespace N {
  struct A {};
  template <class T> int f(T);
}
 int main() {
  int x = f<N::A>(N::A());        // OK: lookup of f finds nothing, f treated as template name
}

GCC和Clang均未编译此简单程序,并且它们发布了类似的诊断:

no templated name f found did you mean N::f?

这显然是一个实现错误,除非有什么不清楚。我应该填写缺陷报告吗?

您引用的规则在C 17中是不同的。变更建议:P0846R0。如果要为C 20编译,则应进行示例编译,如果不编译,则编译器的C 20支持。

没有编译器对C 20的支持稳定,甚至还没有正式发布(虽然最近冻结了功能列表(,因此可以预期有些错误,因为对未来语言版本的支持可能没有完成。

GCC和Clang的最新开发版本成功地编译了示例,因此不需要错误报告。


C 17的标准草稿说:

[basic.lookup.unqual]

在6.4.2中描述了用作函数调用的后缀表达的不合格名称的查找。[注意:为了确定(解析过程(表达式是否是函数调用的后置缩短表达,请使用通常的名称查找规则。6.4.2中的规则对表达的句法解释没有影响。例如,

typedef int f;
namespace N {
    struct A {
        friend void f(A &);
        operator int();
        void g(A a) {
            int i = f(a); // f is the typedef, not the friend function: equivalent to int(a)
        }
    };
}

此示例在clang 5.0.0.0-3〜16.04.1以及GCC 8.2.0中编译了罚款。