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