【发布时间】:2011-05-18 11:54:42
【问题描述】:
关于这个的两个问题:
有没有办法强制
g++忽略throw说明符?
(例如,我记得,Visual Studio 忽略了 throw 说明符,与throw()不同)是否可以强制
g++检查抛出说明符是否正确 - 我的意思是检查(这可以通过 one-pass compilers 完成)如果带有抛出说明符的函数调用函数,这可能只是通过观察他们的抛出说明符和来观察执行throw的异常,这会违反说明符吗? (注意: 这不应该在没有 throw 说明符的情况下观看函数,因为这可能会导致大量警告)
编辑:我将为我的第二个问题添加一些示例。
假设我们有:
// sorry for the coding style here, but I don't want it to be unnecessary long
class A { /* .. */ };
class B : public A { /* .. */ };
class C { /* .. */ };
void no_throw_spec() { /* .. */ }
void no_throw_at_all() throw() { /* .. */ }
void throws_A() throw( A ) { /* .. */ }
// this is fine, don't do anything
void f()
{ no_throw_spec(); no_throw_at_all(); throws_A(); }
void g() throw()
{
no_throw_spec(); no_throw_at_all(); // OK
throws_A(); // warning here - throws_A() may throw A, but g() has throw()!
}
void h() throw( A )
{
no_throw_spec(); no_throw_at_all(); throws_A(); // OK
if( /* .. */ )
throw B(); // OK, B inherits A, it's OK
/* .. */
throw C(); // C does not inherit A, so WARNING!
}
【问题讨论】:
-
我认为 Herb Sutter 关于异常规范的文章仍然适用,即使它已经很老了gotw.ca/publications/mill22.htm
-
我知道。这有什么关系?如果您的意思是,我不应该编写异常规范,我知道。我只是好奇。
-
鉴于 throw 说明符不是函数类型的一部分,C++ 编译器肯定无法在任何可计算的传递次数中一般检查它们。例如,
void doit(void(*f)()) throws() { f(); }。如果(且仅当)f抛出任何东西,doit就会违反其抛出规范。那么编译器是否应该以它可能违反为由拒绝它,因为在编译时没有办法告诉它只会用 nothrow 函数作为参数来调用它? Java 仅通过将 throws 子句作为函数签名的一部分来实现检查异常。 -
或者你的意思是传递的函数在“没有抛出说明符的被调用函数”的标题下?因此编译器接受该代码,即使没有特别的理由相信它不会违反其抛出规范。还要注意,有些标准函数没有记录要抛出的 throw 说明符,例如
std::vector::at,可能您需要使用制造的说明符对它们进行注释,否则它们永远不会被检查。 -
嗯,我还没有考虑过函数指针..但它们可能就像没有任何抛出说明符的函数一样。有关更多信息,请参阅我的编辑(:
标签: c++ g++ compiler-options exception-specification