2 回答
TA貢獻1995條經驗 獲得超2個贊
在C ++ 14中,這顯然是不允許的,盡管在2011這種情況下似乎是明確允許的。目前還不清楚C ++ 11 是否屬于as-if規則,我不相信它會改變,因為它會改變可觀察的行為,但這一點在我在下面引用的問題中并未澄清。
細節
這個問題的答案隨著2013年LWG問題的演變而變化,該問題開始于:
假設特定函數未在標準中標記為constexpr,但在某些特定實現中,可以在constexpr約束內編寫它。如果實施者標記constexpr這樣的功能,是違反標準還是符合標準的擴展?
在C ++ 11中,不清楚as-if規則是否允許這樣做,但是orignal提議一旦被接受就明確允許它,我們可以在下面的gcc bug報告中看到我引用,這是gcc做出的假設球隊。
允許這種轉變的共識在2012年發生了變化并且提案發生了變化,而在C ++ 14中,這是一個不合規的擴展。這反映在草案C ++ 14標準部分17.6.5.6 [constexpr.functions]中,該部分說:
[...]實現不得將任何標準庫函數簽名聲明為constexpr,除非明確要求它。[...]
雖然嚴格閱讀這個內容似乎留下了一些回避處理內置因素的余地,好像它是一個constexpr我們可以從問題中的以下引用中看出,目的是防止實現中的分歧,因為相同的代碼可能會產生不同的行為使用SFINAE時(強調我的):
當向完全委員會提交對WP狀態的投票時表達了一些擔憂,即在沒有充分考慮圖書館實施不同的后果的情況下解決了這個問題,因為用戶可能會使用SFINAE來觀察其他相同代碼的不同行為。
我們可以從gcc bug報告[C ++ 0x] sinh vs asinh vs constexpr看到該團隊依賴早先提出的LWG 2013決議,其中說:
[...]此外,如果該函數的定義滿足必要的約束,則實現可以聲明任何函數為constexpr [...]
在確定是否允許在嚴格一致性模式下對數學函數進行此更改時。
據我所知,如果我們在嚴格的一致性模式下收到警告,即使用-std=c++11 -pedantic或者在此模式下被禁用,這將符合要求。
請注意,我在錯誤報告中添加了一條評論,解釋說自從此問題最初解決后,解決方案已更改。
Jonathan Wakely 在另一個問題中指出了一個更近期的討論,似乎可能會重新打開gcc bug報告來解決這個一致性問題。
本質上怎么樣?
編譯器內在函數不在標準范圍內,因此,據我所知,它們應該免于此規則,因此使用:
static constexpr double a = __builtin_cos(3.);
應該被允許。這個問題出現在錯誤報告中,DanielKrügler的意見是:
[...]庫函數和其他內在函數可能被視為異常,因為它們不需要通過常規語言規則“解釋”。
TA貢獻1856條經驗 獲得超5個贊
我不認為談論編譯器內在函數是有幫助的。所有以名稱開頭的名稱__都保留用于實現,并且實現定義了它們的語義。對于特定于實現的函數的語義是完全合理的,無論它們是否是內在的,都被定義為constexpr純粹由實現者自行決定。
- 2 回答
- 0 關注
- 760 瀏覽
添加回答
舉報
