如果返回类具有析构函数,则忽略gnu :: warn_unused_result属性

时间:2016-11-11 15:38:52

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

我想警告用户他/她是否没有保存某个函数的返回值,但是如果该函数返回一个具有非默认析构函数的类,它就不起作用。

假设以下代码:

struct A {};
struct B { ~B() {} };

[[ gnu::warn_unused_result ]]
A foo() { return A{}; }

[[ gnu::warn_unused_result ]]
B bar() { return B{}; }

int main()
{
    foo(); // warning
    bar(); // no warning
    return 0;
}

使用g ++ 6.2.1编译时,只有foo()会生成警告:

$ g++ -Wall -Wextra ./test.cpp 
./test.cpp: In function ‘int main()’:
./test.cpp:13:9: warning: ignoring return value of ‘A foo()’, declared with attribute warn_unused_result [-Wunused-result]
     foo();
         ^

我理解调用B的析构函数可能会被视为"结果的使用",但问题是:

  • 这是预期的行为还是g ++中的错误/功能?
  • 在这种情况下,有没有办法强制编译器发出警告?
  • C ++ 17' [[ nodiscard ]]的行为是否相同?

1 个答案:

答案 0 :(得分:2)

  

这是预期的行为还是g ++中的错误/功能?

这是一个QoI问题,所有警告都是这样的。 gcc 7 确实发出bar()的警告,所以虽然不是不发出警告的错误,但它更像是gcc 6.2中的遗漏功能。

  

C ++ 17的[[ nodiscard ]]表现相同吗?

这也是实现定义的。 [dcl.attr.nodiscard]的标准中有一个非规范性的注释:

  

外观a   除非明确说明,否则不建议将nodiscard调用作为潜在评估的丢弃值表达式(第5条)   投无效。 鼓励实施在这种情况下发出警告。这通常是因为   丢弃一个nodiscard呼叫的返回值会产生令人惊讶的后果。

在这种情况下,实现不是必需来发出警告。但他们可能会尝试这样做。