"朋友"成员函数和 GCC 与 Clang

`friend` member functions and gcc vs clang

本文关键字:quot Clang GCC 成员 朋友 函数      更新时间:2023-10-16

以下代码片段:

struct a
{
[[nodiscard]] friend int b();
};

使用-std=c++17clang++ (trunk 342102)上编译时产生此错误:

<source>:3:5: error: an attribute list cannot appear here
[[nodiscard]] friend int b();
^~~~~~~~~~~~~

删除friend或向b添加正文可防止错误。

g++ (trunk)编译代码就好了。

神霹雳上的活生生的例子:https://gcc.godbolt.org/z/ttTDuZ


  • 这是一个clang++错误吗?还是标准中的某些规则使此代码格式不正确?

  • 如果clang++是正确的,那么将friend成员函数标记为[[nodiscard]]的正确方法是什么?

per [dcl.attr.grammar]/5

据说每个属性说明符-seq都与某个实体或语句有关,由它出现的语法上下文标识([stmt.stmt], [dcl.dcl], [dcl.decl](。如果适用于某个实体或语句的属性说明符 seq包含不允许应用于该实体或语句的属性对齐说明符,则程序格式不正确。如果属性说明符 seq适用于友元声明,则该声明应为定义。任何属性说明符 seq都不应依赖于显式实例化。

强调我的

所以,叮当就在这里。 如果你有一个属性,那么如果它是友元函数,则该函数必须有一个定义。

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99032

该错误已在 GCC 12 中修复,您现在有以下警告。

test.cpp:3:30: warning: attribute ignored [-Wattributes]
3 |     [[nodiscard]] friend int b();
|                              ^
test.cpp:3:30: note: an attribute that appertains to a friend declaration that is not a definition is ignored

将友元成员函数标记为[[nodiscard]]的正确方法是将属性放在其定义中。

struct a
{
friend int b();
};
[[nodiscard]] int b(){ return 42; }