C ++中的Throw和三元运算符

时间:2011-10-31 18:00:38

标签: c++ operators ternary-operator

以下代码使用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 ++编译?

4 个答案:

答案 0 :(得分:11)

这是标准的C ++。条件表达式中的then / else表达式中的任何一个(或两个)都允许为throw-expression(C ++ 98 5.16 / 2)。

如果Visual Studio在编译时崩溃了......那似乎很不幸!

答案 1 :(得分:4)

Comeau编译它没有错误(这是我最小的可编译测试用例):

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年修复的唯一错误。

答案 2 :(得分:3)

来自C ++ 11月草案

  

§5.16/ 2如果第二个或第三个操作数的类型(可能是cv-qualified)为void,那么左值到右值(4.1),数组到指针(4.2)和函数到 - 指针(4.3)对第二和第三个操作数执行标准转换,并且以下之一应保持:
   - 第二个或第三个操作数(但不是两个)是一个throw-expression(15.1);结果是另一种类型的结果,是一个prvalue    - 第二个和第三个操作数都有类型void;结果是void类型,是一个prvalue。 [注意:这包括两个操作数都是throw-expressions的情况。 - 后注]

似乎throw计为对void的评估,并且这是允许的。

答案 3 :(得分:2)

内部崩溃可被视为Visual Studio的错误。由于编译代码,编译器永远不会崩溃。

这是三元运算符的一个非常奇怪的用法,如果在返回之前这将是一个非常简单的成语:

if(m_something == 0)
    throw std::logic_error("Something wrong happened");

return m_something;