tags:

views:

362

answers:

8

Hello.

While in other statements like if ... else you can avoid braces if there is only one instruction in a block, you cannot do that with try ... catch blocks: the compiler doesn't buy it. For instance:

try
    do_something_risky();
catch (...)
    std::cerr << "Blast!" << std::endl;

With the code above, g++ simply says it expects a '{' before do_something_risky(). Why this difference of behavior between try ... catch and, say, if ... else ?

Thanks!

+5  A: 

Well, first, that's how the grammar works.

Second, I would believe that the goal is to forcibly generate a new scope for the exception blocks(correct me if I'm wrong).

Paul Nathan
+5  A: 

Not sure why, but one benefit is that there is no dangling-catch issue. See dangling-else for an ambiguity that can arise when braces are optional.

R Samuel Klatchko
+1  A: 

That's how they wanted to be. There is no justification, it's a law.

Iulian Şerbănoiu
+11  A: 

Straight from the C++ spec:

try-block:
    try compound-statement handler-seq

As you can see, all try-blocks expect a compound-statement. By definition a compound statement is multiple statements wrapped in braces.

Have everything in a compound-statement ensures that a new scope is generated for the try-block. It also makes everything slightly easier to read in my opinion.

You can check it yourself on page 359 of the C++ Language Specification

Justin Niessner
A: 

Not sure if you're using .NET but the CLR uses the braces as flags.

http://dotnet.sys-con.com/node/44398

From the article: "The SEH (structure exception handling) table consists of a set of clauses that describe the structure of the guarded code. The table has a set of binary flags that describe the type of exception handling clause: a Try Offset flag, which is the beginning of the guarded code block; a Try Length flag, which is the length of the guarded code; Handler Offset and Handler Length flags, which detail the beginning of the exception handler block and its length; and a Class Token or Filter Offset flag, depending on the type of Exception Handler that was defined. This information allows the CLR to determine what to do when an exception occurs. It maps out the beginning of the guarded code block, the code to execute for an exception, and special semantics related to filtering or other special circumstance."

I would assume that other frameworks do the same thing.

Nate Noonen
+2  A: 

Read this link. Most of the reason appears to be about managing the scope and allocation of objects that need to be created and destroyed in case of real exceptions.

So, my guess is, the grammar writers of C++ are asking the authors of g++(or any standards complying C++ compiler) to prepare it for the worst possible cases, and g++ authors appear to have done so.

vpit3833
A: 

Mainly it's because

if (a)
    int b = 10;
else 
    int b = 5;
b += 5;

Will fail because the if...else without {} is a syntax shortcut for this

if (a) {
    int b = 10;
} else {
    int b = 5;
}
b += 5;

which explicitly tells you that int b is in a different scope than the rest of the software.

If I'm not mistaken the following also fails

a ? int b = 10 : int b = 5;
b += 5;

Granted, your compiler might optimize that code for you... but it should technically fail because of the scopes in the if/else statement.

Whenever you see {} you're defining the scope of the software.

-Stephen

Stephen Furlani
good point about the scope, still this does not answer the question (or probably I did not get your point).
nico
Each if, else if, and else block defines its own scope regardless of whether you use braces, so I wouldn't think that you'd need they try or catch blocks to have braces to ensure that they have their own scopes. So, I don't really see how the scoping issue would answer the question - though you do obviously want the try and catch blocks to have their own scopes.
Jonathan M Davis
My comment was that all clauses force scope definition. If/Else statements without {} are a legacy component from when code was written line-by-line - they are a syntaxical short-cut for putting those clauses in. You should always code like the second example. The reason that things like try/catch require {} is that they have no legacy equivalent that needs support.
Stephen Furlani
LOL. Not to be rude, but there are plenty of people who would disagree with you bigtime that you should always use braces in an if/else statement or in a loop. Sure, some people (obviously you included) think that it's good style, but just like folks will argue over the best place to put braces, they'll argue over whether you should always use braces in an if/else statement. I, for one, would argue against it if it's not needed. There are good reasons for both styles, but it's primarily a matter of preference and what works for you.
Jonathan M Davis
+1  A: 

Why? A tradeoff between safety and backwards compatibility.

The lessons learnt from if...else showed that requiring braces eliminates errors. Now, the ISO C++ people have a strong preference for backwards compatibility with C, so they didn't change the C syntax for if...else. But new constructs require braces to demarcate controlled blocks, as they won't appear in old C code and therefore backwards compatibility is not a concern.

MSalters