2012-12-03 20 views
5

我有下面的代碼:爲什麼g ++不會在啓用`-fpic`的情況下發出這個構造函數相關的noexcept警告?

#include <exception> 
#include <cstdlib> 

void g() { throw 1; } 
void (*p)() = g; 

template <class T> 
void f(T) noexcept (noexcept (T())) // warning 1 
{ 
    p(); 
} 

struct A { A() { } };   // warning 2 

int main() 
{ 
    try { f(A()); } catch (int) { } 
    return 1; 
} 

並與未來的選擇:
-fno-pic -fmessage-length=0 -std=c++0x -Wnoexcept
G ++拋出下一個警告:

noexcept03.C:16:6: warning: noexcept-expression evaluates to 'false' because of a call to 'A::A()' [-Wnoexcept] 
noexcept03.C:21:12: warning: but 'A::A()' does not throw; perhaps it should be declared 'noexcept' [-Wnoexcept] 

但爲什麼當我使用的-fpic代替-fno-picg++不會拋出任何警告?

編輯:
版本的GCC - 4.7.2

+0

要使用哪個版本的gcc進行編譯? –

+0

@kumar_m_kiran 4.7.2 – Arseniy

回答

5

警告未在-fpic情況下發出的,因爲編譯器假定構造A::A()可以拋出。

編譯PIC代碼時,GCC假定每個全局名稱都可以被來自其他模塊的符號覆蓋。因此,由於沒有明確的noexcept聲明,GCC必須保守地認爲這樣的函數可以拋出異常,即使它可以靜態證明它現在看到的版本不能。

僅供參考,請參閱錯誤,這裏的補丁http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29323#c7(代碼已經改變了一點,但它開始像這樣)

一個例子,上述哪裏是適用的:

/* inline */ int f() { return 0; } 

int g() noexcept (noexcept(f())) { return f() + 1; } 

因此,這是「爲什麼」沒有警告的直接原因。接下來是我的想法。

然而,C++ 11表示:

7.1.2功能說明符[dcl.fct.spec]

4內聯函數應每翻譯單元被限定在 它是odr-used和應該在 中具有完全相同的定義,每種情況(3.2)。

即對於內聯函數,如果函數被確定爲不拋出,GCC可以假定每個這種函數的潛在覆蓋都不能拋出。

從這個意義上說,GCC對於內聯函數過於保守,並且在原始測試用例和上述示例中關於inline關鍵字未註釋,即使使用-fpic/-fPIC,GCC也應該發出警告。

+0

嗨,謝謝你的回答。你在哪裏得到這個 '當編譯PIC代碼時,GCC假定每個全局名稱都可以被來自其他模塊的符號覆蓋'我的意思是某些書/源?請提供鏈接。 – Arseniy

+0

@Pepelac,源代碼是GCC源代碼:)順便說一句,這種行爲不是PIC代碼專用的,對弱函數和其他一些情況也是如此。 – chill

+0

再次感謝我已經找到它在GCC代碼中實現的位置,但我認爲你可能從某些手冊中獲得它) – Arseniy

相關問題