下面的代碼編譯與G ++ 4.6.1,但不與Visual Studio 2008投擲和三元運算++
return (m_something == 0) ?
throw std::logic_error("Something wrong happened") : m_something;
事實是在Visual Studio編譯器執行的內部碰撞。
我想知道這是標準的C++,爲什麼它不用Visual Studio編譯,但用G ++嗎?
下面的代碼編譯與G ++ 4.6.1,但不與Visual Studio 2008投擲和三元運算++
return (m_something == 0) ?
throw std::logic_error("Something wrong happened") : m_something;
事實是在Visual Studio編譯器執行的內部碰撞。
我想知道這是標準的C++,爲什麼它不用Visual Studio編譯,但用G ++嗎?
它是標準的C++。條件表達式中的then/else表達式中的任何一個(或兩者)允許爲throw-expression(C++ 98 5.16/2)。
如果Visual Studio在編譯時崩潰......這似乎是不幸的!
§5.16/ 2允許這兩個表達式在C++ 11中都是拋出表達式。 – Mat
@Mat:oops,你說的很對,這裏的文本沒有改變,第二個選擇也允許在C++ 98中拋出。 –
科莫編譯它沒有錯誤(這是我最小的編譯測試用例):
int main(void)
{
int x = 17;
return x ? throw "Something wrong happened" : 5;
}
這是非常好的證據表明它是由標準允許的。所以是MSVC崩潰的事實,而不是乾淨地與一個錯誤失敗。
而且,它似乎被固定在VC++ 2010
R:\>cl ternarythrowtest.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
ternarythrowtest.cpp
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:ternarythrowtest.exe
ternarythrowtest.obj
和x64版本:如果可能的話
R:\>cl ternarythrowtest.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.40219.01 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
ternarythrowtest.cpp
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:ternarythrowtest.exe
ternarythrowtest.obj
升級你的編譯器,這是遠遠固定在2010年
唯一的錯誤確實,這可能是因爲遵循C++ 11,請參閱@ MooingDuck的答案。 –
@AndréCaron:這無法解釋「內部編譯器錯誤」。看到John的答案,它也允許在C++ 98中使用。 –
我在@ fmorency的團隊,我是用他的三元運算符表達式遇到Microsoft Compiler崩潰的人。我們試圖弄清楚它是否是標準的,而不是這是否是微軟編譯器中的一個錯誤(顯然存在* a *錯誤,因爲它是崩潰的)。 –
從C++ 2月11日草案
§5.16/2如果第二或第三操作數的類型(可能CV-合格)無效,那麼左值到右值(4.1) ,數組到指針(4.2)和函數到指針(4.3)的標準轉換在第二個和第三個操作數上執行,並且下列之一成立:
- 第二個或第三個操作數(但不是兩者)是一個投擲表達式(15.1);結果是另一種的類型,是一個價值。
- 第二個和第三個操作數的類型都是void;結果是void類型並且是一個prvalue。 [注意:這包括兩個操作數都是throw-expressions的情況。 - 注意]
看來throw
計爲評估void
,這是允許的。
C++ 11與VS2008幾乎沒有關係(除了這不是C++ 11規則,它自C++ 98以來一直沒有變化,請參閱John的答案)。 –
我沒有C++ 03草稿(適用於VS2008)的引用,或者我會引用它。你說得對,它不一定適用於VS2008。 –
內部崩潰可被視爲Visual Studio的錯誤。編譯器永遠不會崩潰,因爲正在編譯的代碼。
這是三元運算符的一個很奇怪的用法,簡單的,如果之前的回報將是一個更加理想的成語:
if(m_something == 0)
throw std::logic_error("Something wrong happened");
return m_something;
無論這是有效的代碼或不按標準,當一個編譯器崩潰時出現內部編譯器錯誤(這是VC所做的,IIUC),那麼這是編譯器中的錯誤。編譯器應該發出一個有意義的消息,即使是錯誤的代碼,而不是崩潰報告。 – sbi
請記住,這是*條件運算符*,它恰好是* a *三元運算符。 – GManNickG
是的,當「三元」不在規範的任何地方時,感到困惑。 –