当返回类型是类时,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不喜欢这个特定的函数声明?
答案 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;