返回类型为类时,带尾随返回类型的GCC属性警告

时间:2014-12-10 19:07:52

标签: c++ c++11 gcc

当返回类型是类时,GCC 4.9.1似乎不喜欢带有属性的尾随返回类型的函数声明。

考虑以下简单的测试用例:

struct bar
{
    int a;
    bar (int a) : a(a) {}
};

auto foo() -> bar __attribute__((unused));
auto foo() -> bar { return bar(5); }

int main()
{
    return 0;
}

GCC打印关于属性的奇怪警告:

argh.cpp:2:41: warning: ignoring attributes applied to class type ‘bar’ outside of definition [-Wattributes]
 auto foo() -> bar __attribute__((unused)) {return bar(5);}

将声明与定义合并不会使警告静音,这仅在返回类型为类类型时才会发生,它与int一起正常工作。到底是怎么回事?为什么GCC不喜欢这个特定的函数声明?

3 个答案:

答案 0 :(得分:2)

似乎是GCC使用的属性解析器中的错误。 GCC手册警告属性语法的潜在问题:

6.31属性语法

  

由于属性的语法不灵活,有些形式   此处描述的内容可能无法在所有情况下成功解析。

     

C ++中的属性语义存在一些问题。 [...]例如,虽然属性可能会影响代码生成,但属性没有修改,因此当属性类型与模板一起使用或重载时可能会出现问题。

关于尾随返回类型之后的属性解析的警告也会有所帮助。

  

属性说明符列表可能出现在声明者之前   [...]

您应该尝试将该属性放在原型之前:

 __attribute__((unused)) 
auto foo() -> bar ;
auto foo() -> bar { return bar(5); }

并且没有任何警告就应该没问题。

  

属性说明符列表可能出现在逗号之前,=   或分号终止除a之外的标识符的声明   功能定义。这些属性说明符适用于声明的   对象或功能。

我想在函数声明之后定位函数属性是正常的,除非有尾随的返回类型。

答案 1 :(得分:1)

Clang(像往常一样)在这种情况下给出了更好的警告:

example.cpp:7:34: warning: 'unused' attribute ignored when parsing type
      [-Wignored-attributes]
auto foo() -> bar __attribute__((unused));
                                 ^~~~~~
1 warning generated.

就像GCC告诉你的那样,该属性在您使用它的上下文中毫无意义。它在概念上与做类似的事情相同:

const int f(void) { return 5 };

const只是

答案 2 :(得分:1)

GCC manual意味着目前不支持语法。

  

将来可以允许显示属性说明符列表   在函数定义中的声明符之后(在任何旧式之前)   参数声明或函数体。)

N3337描述了[dcl.fct.def]中函数定义的语法:

  

函数的定义:

     

attribute-specifier-seq opt decl-specifier-seq opt declarator virt-specifier -seq opt function-body

     

...

     

2 函数定义中的声明符应具有

形式      
    

D1 parameter-declaration-clause )      CV-限定符-SEQ <子>选择

         

REF-限定符 <子>选择     例外规范 opt attribute-specifier-seq opt trailing-return-type <子>选择

  

正如您所看到的, trailing-return-type function-body 之前出现的声明符的一部分。尝试将代码更改为:

auto __attribute__((unused)) foo() -> bar;