C++ C+中的Throw和三元运算符+;
以下代码使用G++4.6.1编译,但不使用Visual Studio 2008C++ C+中的Throw和三元运算符+;,c++,operators,ternary-operator,C++,Operators,Ternary Operator,以下代码使用G++4.6.1编译,但不使用Visual Studio 2008 return (m_something == 0) ? throw std::logic_error("Something wrong happened") : m_something; 事实是VisualStudio编译器执行内部崩溃 我想知道这是不是标准C++,为什么它不使用VisualStudio编译,但是用G++ +?< /P> < P> COMUO编译它没有错误(这里是我的最小可编译测试用例):
return (m_something == 0) ?
throw std::logic_error("Something wrong happened") : m_something;
事实是VisualStudio编译器执行内部崩溃
我想知道这是不是标准C++,为什么它不使用VisualStudio编译,但是用G++ +?< /P> < P> COMUO编译它没有错误(这里是我的最小可编译测试用例):
这是标准允许的很好的证据。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。< /P> < P>它是标准C++。条件表达式中的then/else表达式之一(或两者)可以改为THOW表达式(C++98 5.16/2)
如果Visual Studio在编译时崩溃。。。那似乎很不幸 来自2月11日的C++11草案 §5.16/2如果第二个或第三个操作数的类型(可能是cv限定的)为void,则对第二个和第三个操作数执行左值到右值(4.1)、数组到指针(4.2)和函数到指针(4.3)的标准转换,并且以下之一应保持不变:
-第二个或第三个操作数(但不是两者)是一个抛出表达式(15.1);结果属于另一种类型,是一个PR值。
-第二个和第三个操作数都具有void类型;结果为void类型,是一个prvalue。[注:这包括两个操作数都是抛出表达式的情况。-结束注]
看来
throw
计算为void
,这是允许的。内部崩溃可以被视为Visual Studio的一个bug。编译器永远不会因为正在编译的代码而崩溃
这是三元运算符的一个非常奇怪的用法,在返回之前使用一个简单的if是一个更好的习惯用法:
if(m_something == 0)
throw std::logic_error("Something wrong happened");
return m_something;
§5.16/2允许这两个表达式在C++11中都是抛出表达式。@Mat:oops,你说得很对,这里的文本没有改变,第二个选项也允许这两个表达式在C++98中抛出。事实上,这可能是因为C++11合规性,请参阅@MooingDuck的答案。@AndréCaron:这无法解释“内部编译器错误”。看看John的答案,C++98中也允许这样做。我是@fmorence团队的成员,我是那个用三元运算符表达式抛出的Microsoft编译器崩溃的人。我们试图弄清楚它是否是标准的,而不是这是否是微软编译器中的一个bug(显然有一个bug,因为它崩溃了)。@AndréCaron:好吧,这是C++98,不是C++11的合规性问题,所以它肯定能工作。的确:-)。不幸的是,我们目前还停留在Qt4.7上,而且我们支持Windows,所以我们停留在VS2008的编译器上。C++11与VS2008几乎没有什么关系(除了这不是C++11规则,自C++98以来没有变化,请参见John的回答)。我没有一份C++03草稿(用于VS2008)的副本可以引用,否则我会引用它。你说得对,它不一定适用于VS2008。但是,不管这是有效代码还是不符合标准,当编译器因内部编译器错误(VC就是这样做的,IIUC)而崩溃时,那就是编译器中的错误。编译器即使对于错误代码也应该发出有意义的消息,而不是崩溃报告。请记住,这是条件运算符,它恰好是三元运算符。是的,当规范中没有“三元”时,我感到困惑。有一段时间(在c++11和c++14之间)从三元组抛出是编写可能在编译时失败的constexpr函数的唯一方法。
if(m_something == 0)
throw std::logic_error("Something wrong happened");
return m_something;