2017-01-18 40 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