亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

它是一個符合標準的編譯器擴展,將非constexpr標準庫函數視為constexpr嗎?

它是一個符合標準的編譯器擴展,將非constexpr標準庫函數視為constexpr嗎?

C++
慕桂英4014372 2019-08-28 14:11:25
它是一個符合標準的編譯器擴展,將非constexpr標準庫函數視為constexpr嗎?gcc 在沒有警告的情況下編譯以下代碼:#include <cmath>struct foo {   static constexpr double a = std::cos(3.);   static constexpr double c = std::exp(3.);   static constexpr double d = std::log(3.);   static constexpr double e1 = std::asin(1.);   static constexpr double h = std::sqrt(.1);   static constexpr double p = std::pow(1.3,-0.75);};int main(){}的上面使用的標準庫函數都不是constexpr功能,我們允許使用它們,其中一個常量表達式從兩個需要草案C ++ 11標準和草案C ++ 14標準部7.1.5 [dcl.constexpr] :[...]如果它是由構造函數調用初始化的,那么該調用應該是一個常量表達式(5.19)。否則,或者如果在引用聲明中使用constexpr說明符,則其初始值設定項中出現的每個完整表達式都應為常量表達式。[...]即使使用-std=c++14 -pedantic 或-std=c++11 -pedantic沒有生成警告(請參見實時)。使用-fno-builtin產生錯誤(參見實時),表明這些標準庫函數的內置版本被視為constexpr雖然clang不允許使用任何標志組合的代碼我嘗試過。所以這是一個gcc擴展來處理至少一些內置函數,好像它們是constexpr函數,即使標準沒有明確要求它們。我本來期望至少在嚴格的一致性模式下收到警告,這是一個符合標準的擴展嗎?
查看完整描述

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的意見是:

[...]庫函數和其他內在函數可能被視為異常,因為它們不需要通過常規語言規則“解釋”。


查看完整回答
反對 回復 2019-08-28
?
RISEBY

TA貢獻1856條經驗 獲得超5個贊

我不認為談論編譯器內在函數是有幫助的。所有以名稱開頭的名稱__都保留用于實現,并且實現定義了它們的語義。對于特定于實現的函數的語義是完全合理的,無論它們是否是內在的,都被定義為constexpr純粹由實現者自行決定。

查看完整回答
反對 回復 2019-08-28
  • 2 回答
  • 0 關注
  • 760 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號