为什么三元操作失败没有被try catch捕获
Why Ternary operation failure not cought in try catch
我指的是代码 here。然后我如下修改它,以捕捉失败。但是代码在没有捕获异常的情况下失败了。如何处理(捕获)这个失败?
#include <iostream>
#include <exception>
using namespace std;
int main()
{
int test = 0;
cout << "test set to 0" << endl;
try {
cout << (test ? "A String" : 0) << endl;
} catch(...) {
cout << "Exception" << endl;
}
cout << "Test done" << endl;
return 0;
}
你的代码没有抛出任何异常,"A String"
的类型是const char*
,所以是一个指针,而0
可以被评估为NULL
,一个指针同样,这意味着 test ? "A String" : 0
returns const char*
,那里没有错误。
另外我认为你不知道异常是如何工作的,如果你的代码有这样的错误
test ? std::string{"A String"} : nullptr
,该错误将是编译时错误,而不是异常,因为编译器将无法为这两种类型找到通用类型。
C++ 与大多数其他语言不同,它具有 未定义行为 的概念。这意味着无效操作不会导致异常,但会导致崩溃、数据损坏或其他任何事情。 C++ 中的 exception 是代码显式 throw
s 和 catch
es 的东西。你的代码不是这种情况。
(test ? "A String" : 0)
的结果是const char *
。所以 0
被转换为 const char *
,即 NULL 指针。标准库有一个 overload for operator <<
期望 const char *
是一个非 NULL C 字符串。
即operator <<
根本不检查输入参数是否为NULL。引用 NULL 指针是未定义的行为。在大多数系统上,它会导致 OS 级别的分段错误和程序终止。
为了完整起见,在 MSVC 中,您可以使用 /EHa
进行编译,将 SEH 异常视为 C++ 异常,然后 catch(...)
也会捕获这些异常。但不要使用此功能,因为它会导致资源泄漏和不可移植、不可维护的代码。
我指的是代码 here。然后我如下修改它,以捕捉失败。但是代码在没有捕获异常的情况下失败了。如何处理(捕获)这个失败?
#include <iostream>
#include <exception>
using namespace std;
int main()
{
int test = 0;
cout << "test set to 0" << endl;
try {
cout << (test ? "A String" : 0) << endl;
} catch(...) {
cout << "Exception" << endl;
}
cout << "Test done" << endl;
return 0;
}
你的代码没有抛出任何异常,"A String"
的类型是const char*
,所以是一个指针,而0
可以被评估为NULL
,一个指针同样,这意味着 test ? "A String" : 0
returns const char*
,那里没有错误。
另外我认为你不知道异常是如何工作的,如果你的代码有这样的错误
test ? std::string{"A String"} : nullptr
,该错误将是编译时错误,而不是异常,因为编译器将无法为这两种类型找到通用类型。
C++ 与大多数其他语言不同,它具有 未定义行为 的概念。这意味着无效操作不会导致异常,但会导致崩溃、数据损坏或其他任何事情。 C++ 中的 exception 是代码显式 throw
s 和 catch
es 的东西。你的代码不是这种情况。
(test ? "A String" : 0)
的结果是const char *
。所以 0
被转换为 const char *
,即 NULL 指针。标准库有一个 overload for operator <<
期望 const char *
是一个非 NULL C 字符串。
即operator <<
根本不检查输入参数是否为NULL。引用 NULL 指针是未定义的行为。在大多数系统上,它会导致 OS 级别的分段错误和程序终止。
为了完整起见,在 MSVC 中,您可以使用 /EHa
进行编译,将 SEH 异常视为 C++ 异常,然后 catch(...)
也会捕获这些异常。但不要使用此功能,因为它会导致资源泄漏和不可移植、不可维护的代码。