9

同時產生了this問題,我偶然發現了一個MCVE,我發現編譯器之間的差異如下:在另一個函數內部的`constexpr`函數的前向聲明 - 編譯器錯誤?

考慮下面的代碼:

// constexpr int f(); // 1 

constexpr int g() { 
    constexpr int f(); // 2 
    return f(); 
} 

constexpr int f() { 
    return 42; 
} 

int main() { 
    constexpr int i = g(); 
    return i; 
} 

此代碼編譯上鐺3.8.0,但失敗在GCC 6.1.0有:

error: 'constexpr int f()' used before its definition 

註釋掉// 2和取消註釋在兩種編譯器// 1作品。

有趣的是,移動f的代替// 1編譯定義,但在觸發一個// 2警告:

warning: inline function 'constexpr int f()' used but never defined 

哪個編譯器是正確的?

回答

2

inline功能更換constexpr功能保留了完全相同的問題(它是好的,與全局聲明1,但不與功能範圍的聲明2)由於constexpr意味着inline這似乎是原因。

在這種情況下,聲明2,GCC抱怨: warning: 'inline' specifier invalid for function 'f' declared out of global scopewarning: inline function 'int f()' used but never defined。 鏈接失敗(「undefined reference to 'f()'」)。

因此,它看起來像放棄了內聯,打電話,但不打擾f()發出的代碼,因爲所有用途都內聯(?),所以鏈接失敗。

和鏘抱怨: error: inline declaration of 'f' not allowed in block scope

由於constexpr意味着inline,似乎這條規則內聯聲明未在塊允許的範圍也應適用於constexpr,因此GCC是正確的。但是這個標準似乎沒有出來並且說這個。在我檢查的草案中,有關inline的規則在§7.1.2[dcl.fct.spec]中,第3部分:「內聯說明符不應出現在塊作用域函數聲明中」,但是關於constexpr沒有出現類似內容。