【发布时间】:2009-06-24 13:46:32
【问题描述】:
捕获的 std::exception 是否可以让 what() 为 NULL?
检查 e.what() 是否低于开销?
//...
}
catch (const std::exception& e)
{
std::string error;
if(e.what())
error = e.what();
}
【问题讨论】:
捕获的 std::exception 是否可以让 what() 为 NULL?
检查 e.what() 是否低于开销?
//...
}
catch (const std::exception& e)
{
std::string error;
if(e.what())
error = e.what();
}
【问题讨论】:
字符串的内容是实现定义的,所以我猜答案是肯定的。
编辑:保护它。标准说:
virtual const char* what() const throw();
5 Returns: An implementation-defined NTBS.
所以它必须返回一个字符串,而不仅仅是一个指针。并且字符串不能是NULL。正如其他人所指出的,很容易推导出 what() 确实返回 NULL 的异常,但我不确定这些事情如何符合标准一致性。当然,如果您在自己的异常类中实现 what(),我会认为允许它返回 NULL 是非常糟糕的做法。
更多:
有关what() 是否可以返回 NULL 的进一步问题以及类似的令人兴奋的问题,请参阅Extending the C++ Standard Library by inheritance?
【讨论】:
如果有人从 std::exception 继承并重写了返回 NULL 的内容,那么这是可能的。
class CMyException : public std::exception
{
...
virtual const char * what () const {return NULL;}
};
尽管 Neil 在标准中找到了出色的发现,但检查 NULL 可能仍然很好。尽管 std::exception 的哪些子类的规范表明它们不应返回 NULL,但编译器中的任何内容都不会强制执行此操作,并且根据语言,上述代码仍然是合法的。
这可能是使用断言的理想情况...
assert(except.what() != NULL);
或
if (except.what() != NULL)
{
... normal processing ...
}
else
{
assert(false);
}
因为在这种情况下,某些事情可能永远不会发生,并且您假设它不应该发生,但仍然想知道(在调试模式下)您的假设何时被证明是错误的。然后您可以解决您的错误假设或解决可能与您的假设相反的错误代码(确保 what() 不返回 NULL)。
【讨论】:
当然可以是NULL:
class myexception: public exception
{
virtual const char* what() const throw()
{
return NULL;
}
} myex;
【讨论】:
正如许多其他人指出的那样,what() 不应该返回一个空指针,但它可能。空测试的运行时开销仅在可能不太重要的例外情况下发生。
无论如何,我建议至少使用assert。
如果代码空间也是一个问题,希望assert、您的测试、代码审查和其他 QA 将足够完整,以便在您发布之前追踪任何违规、不合规的异常。
此外,请注意自身可能抛出的异常处理代码(例如,正如其他人所指出的,在处理 std::bad_alloc 异常时使用 std::string 分配内存。)
【讨论】: