2017-01-18 15 views
2

鉴于此代码:GCC错误:功能可能是候选属性“纯”,如果它被称为正常返回

#include <cstdlib> 

void func(int x) 
{ 
    if (x) 
    abort(); 
}; 

g++ -Werror=suggest-attribute=pure抱怨:

error: function might be candidate for attribute ‘pure’ if it is known to return normally

这似乎很奇怪,以我 - 是不是明显知道该函数不能正常返回?有什么办法可以告诉GCC它并不总是正常返回,或者我不希望这个警告出现在这个特定的函数中?

演示:https://godbolt.org/g/720VOT

+1

功能没有任何影响,但返回的值(即是一个_no effect_本身)并且该值取决于(仅)参数。这似乎是一个好的候选人。为什么不? – skypjack

+0

@skypjack:该函数确实有副作用 - 它可以调用abort()来结束程序。我认为这意味着它不是“纯粹”优化的候选者。你有其他想法吗? –

+1

哦,你希望编译器知道这是'中止'。那么,想象一下你使用一个指向你分配'abort'的函数的指针,你的期望会是一样的吗?我不认为它检查函数,它只是接受它作为一个'void(void)'函数类型被调用,不影响返回的值。因此后者仅取决于参数,功能是“纯”的。 – skypjack

回答

1

这似乎是一个错误在海湾合作委员会(或文档和实际执行的至少差异)。该documentation on -Wsuggest-attribute=pure写着:

-Wsuggest-attribute=pure
-Wsuggest-attribute=const
-Wsuggest-attribute=noreturn

Warn about functions that might be candidates for attributes pure , const or noreturn . The compiler only warns for functions visible in other compilation units or (in the case of pure and const) if it cannot prove that the function returns normally. A function returns normally if it doesn't contain an infinite loop or return abnormally by throwing, calling abort or trapping. This analysis requires option -fipa-pure-const , which is enabled by default at -O and higher. Higher optimization levels improve the accuracy of the analysis.

然而,实际的分析似乎忽略不回电话的可能性,虽然它尊重可能的例外:

$ cat test-noreturn.cpp 
[[noreturn]] void foo(); 

void func(int x) 
{ 
    if (x) 
     foo(); 
} 

$ g++ -std=c++11 -c -O -Wsuggest-attribute=pure test-noreturn.cpp 
$ cat test-noreturn-nothrow.cpp 
[[noreturn]] void foo() throw(); 
//      ^^^^^^^ 

void func(int x) 
{ 
    if (x) 
     foo(); 
} 
$ g++ -std=c++11 -c -O -Wsuggest-attribute=pure test-noreturn-nothrow.cpp 
test-noreturn-nothrow.cpp: In function ‘void func(int)’: 
test-noreturn-nothrow.cpp:4:6: warning: function might be candidate for attribute ‘pure’ if it is known to return normally [-Wsuggest-attribute=pure] 
void func(int x) 
    ^
+0

我不会称之为_bug_,而是在分析过程中缺少精确度。这表示“如果已知正常返回”,这应该告诉我们,编译器未能证明某些关于功能的特性,但仍然发出警告,希望得到最好的结果。 Noreturn功能非常频繁,所以我建议在[GCC BZ](https://gcc.gnu.org/bugzilla/)中提交PR。 – yugr