Bid*_*dou 43 c++ syntax try-catch
而在if等中的其他语句中,如果块中只有一条指令,则可以避免使用大括号,而不能使用try ... catch块执行此操作:编译器不会购买它.例如:
try
do_something_risky();
catch (...)
std::cerr << "Blast!" << std::endl;
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,g ++只是说它在do_something_risky()之前需要一个'{'.为什么这种行为的差异尝试...捕获,比如说,如果......其他?
谢谢!
Jus*_*ner 13
直接来自C++规范:
try-block:
try compound-statement handler-seq
Run Code Online (Sandbox Code Playgroud)
如你所见,所有人都try-block期待着compound-statement.根据定义,复合语句是用大括号包装的多个语句.
将复合语句中的所有内容都确保为try-block生成新范围.在我看来,这也使得一切都更容易阅读.
您可以在C++语言规范的第359页上自行查看
try-block的语法是:
try compound-statement handler-sequence
Run Code Online (Sandbox Code Playgroud)
其中handler-sequence是一个或多个处理程序的序列,具有以下语法:
catch (type-specifier-seq declarator) compound-statement
catch (...) compound-statement
Run Code Online (Sandbox Code Playgroud)
这与控制语句等其他语句不同(if,while,for等).这些的语法是:
if (condition) statement-true else statement-false
while (condition) statement
for (init-statement; condition; iteration_expression) statement
etc.
Run Code Online (Sandbox Code Playgroud)
现在,问题是为什么try-block而不是单个语句需要复合语句?
想想这段代码:
int main()
{
// before try-statement.
try g(); catch (std::runtime_error e) handleError(e);
// after try-statement.
}
Run Code Online (Sandbox Code Playgroud)
我知道,按值捕获是一种不好的做法(例如可能的对象切片等),但我这样做是为了防止讨论异常的存储持续时间并使其易于推理.
现在想想,关于'e'的存储持续时间和联系.您期望的是,'e'只能在调用handleError函数之前引用,但在调用完成后才会引用.它应具有自动存储持续时间,并且在此"范围"中没有链接.这可能通过隐式定义局部作用域来完成,就像在其他语句中一样,但是使异常声明看起来像一个函数参数可能是一个更好的主意.所以需要块(复合语句).Se bellow.
现在考虑一下尝试和之后的声明.没有理由使用关键字try那里,没有理由使用复合语句,但语法可能会变得模糊和复杂.
这就是Stroustrup在C++的异常处理中所说的:
It might be possible to simplify the
try { ... } catch (abc) { ... }
syntax by removing the apparently redundant try keyword,
removing the redundant parentheses, and by allowing a handler
to be attached to any statement and not just to a block. For
example, one might allow:
void f()
{
g(); catch (x1) { /* ... */ }
}
as an alternative to - 28 -
void f()
{
try { g(); } catch (x1) { /* ... */ }
}
The added notational convenience seems insignificant and may not
even be convenient. People seem to prefer syntactic constructs that
start with a prefix that alerts them to what is going on, and it may
be easier to generate good code when the try keyword is required.
Run Code Online (Sandbox Code Playgroud)
经过更详细的解释:
Allowing exception handlers to be attached to blocks only and not to
simple statements simplifies syntax analysis (both for humans and
computers) where several exceptions are caught and where nested
exception handlers are considered (see Appendix E). For example,
assuming that we allowed handlers to be attached to any statement
we could write:
try try f(); catch (x) { ... } catch (y) { ... } catch (z) { ... }
The could be interpreted be in at least three ways:
try { try f(); catch (x) { ... } } catch (y) { ... } catch (z) { ... }
try { try f(); catch (x) { ... } catch (y) { ... } } catch (z) { ... }
try { try f(); catch (x) { ... } catch (y) { ... } catch (z) { ... } }
There seems to be no reason to allow these ambiguities even if there
is a trivial and systematic way for a parser to chose one
interpretation over another. Consequently, a { is required after a
try and a matching } before the first of the associated sequence of
catch clauses.
Run Code Online (Sandbox Code Playgroud)
正如Stroustrup所说,没有括号,声明可能意味着不同的东西取决于规则,你可能需要用括号来澄清内涵.在Stroustrup的例子中,我们可以使用if语句制作一些看起来很复杂的东西吗?当然我们可以这样,例如:
if (c1) if (c2) f(); else if (c3) g(); else h();
Run Code Online (Sandbox Code Playgroud)
这实际上相当于:
if (c1) { if (c2) f(); else { if (c3) g(); else h(); } }
Run Code Online (Sandbox Code Playgroud)
但我认为这比try-block的问题要少.if-statament有两种语法:
if (condition) statement-true
if (condition) statement-true else statement-false
Run Code Online (Sandbox Code Playgroud)
因为有时候不采取其他行动是有道理的.但是没有catch-clause的try-block就没有意义.正如Stroustrup所说,'try'可以省略但不实用,但是如果指定了try-block,则catch-clause不能.除此之外,可能存在多个与同一个try-block相关的catch,但只有一个基于依赖于catch-clauses的异常类型和顺序的规则执行.
现在,如果if-else的语法更改为:
if (condition) compound-statement-true else compound-statement-false
Run Code Online (Sandbox Code Playgroud)
那么,你必须写if-else像这样:
if (c1) { f(); } else { if (c2) { g(); } else { h(); } }
Run Code Online (Sandbox Code Playgroud)
看到没有'elseif'关键字,'else if'没有特殊语法.我认为即使是"总是戴上牙套"的防守者也不喜欢这样写,而是写下来:
if (c1) { f(); } else if (c2) { g(); } else { h(); }
Run Code Online (Sandbox Code Playgroud)
我认为这不是一个强有力的理由来定义上面的语法,并在语言中引入'elseif'关键字或为'else if'定义一个特殊的语法.
为什么?安全性和向后兼容性之间的权衡.
从if ......中得到的教训表明,需要括号可以消除错误.现在,ISO C++人员强烈倾向于向后兼容C,因此他们没有更改if ... else的C语法.但是新构造需要大括号来划分受控块,因为它们不会出现在旧C代码中,因此向后兼容性不是问题.
| 归档时间: |
|
| 查看次数: |
3350 次 |
| 最近记录: |