Why braces around try/catch?

  • Thread starter Henrik S. Hansen
  • Start date
T

Thomas G. Marshall

Jacob said:
In 15 years of C++ and Java I have never made
such an error. My editor (emacs) will reindent
code immediately, and the lack of braces whould
become immediately apparent.

In 20+ years of C and Java, I don't think I have either, and with WITHOUT
syntax/grammer help.

But here's the point: Even if I had made that error, say, 5 times. It's
hardly an issue to give up the improved readability for.
 
V

Virgil Green

Jacob said:
In 15 years of C++ and Java I have never made
such an error. My editor (emacs) will reindent
code immediately, and the lack of braces whould
become immediately apparent.

So, does this mean that you *have* made the error but immediately corrected
it because your editor made it readily apparent?

- Virgil
 
B

Bent C Dalager

There's no doubt that things like:

if (a)
b;
c;

fall into the clever classroom bugs category.

I have seen this bug in production code, and it can be quite
insidious. I only trapped it because I started wondering why the
debugger was jumping around in such a non-conventional manner :)

It wasn't even the bug I was looking for (or so it told me, and waved
its hand ... hmmm). In stead, it was a latent bug that would show up
one time out of a million and do something slightly wrong. But not
sufficiently wrong that anyone had cried up about it. Yet.

Cheers
Bent D
 
M

Miguel De Anda

Henrik S. Hansen said:
Does anyone know why braces are required around a try/catch block of
code? It seems counter-intuitive, since if/else etc. accept a single
statement without braces.

I think it's to annoy people who don't handle errors.

If braces were not required, people would often be tempted to write code
like this:

try dangerMethod(); catch(Exception gripe) someStatement;

Or better yet:

try dangerMethod(); catch(Exception gripe);

Which would be similar to:

for(int i=0; i<5; i++);

And simply ignore the exception. There is already too much code with:

try { dangerMethod(); } catch(Exception gripe) { }

And I believe that the java people knew this would happen and simply made it
required to remind people to put something in there.
 
T

Thomas G. Marshall

Tor Iver Wilhelmsen said:
"Thomas G. Marshall"


So would you want the same in *every* situation where there is only
one statement in a block? e.g.

public int getFoo() return 42;

for instance? The parser can easily handle that, too.

The problem with allowing brace-less single-statement-ifs and the like
is that you then have two syntaxes for essentially the same thing: One
with, and one without the braces, the difference being the number of
statements (0-1 vs. 0-n). In the compiled code, there IS no semantic
difference - a branch does not care how many statements it skips. Why
should the language differentiate?

Using your logic there shouldn't be any literals per se. Everything should
be single element arrays for literals.

int[] a = {1};
a[0]++;

In the case of a single element, the compiler CERTAINLY knows not to use
index code unecessasrily.

So your words apply: "Why should the language differentiate?"

The answer is that there is /no/ reason for a language to be consistant to
the extent that readability suffers.

You need only one of while, for, do loops, so why all three?

Readability. And readability over the lifecycle of a product directly
influences maintainability.
 
T

Tor Iver Wilhelmsen

Thomas G. Marshall said:
But here's the point: Even if I had made that error, say, 5 times.
It's hardly an issue to give up the improved readability for.

So would you want the same in *every* situation where there is only
one statement in a block? e.g.

public int getFoo() return 42;

for instance? The parser can easily handle that, too.

The problem with allowing brace-less single-statement-ifs and the like
is that you then have two syntaxes for essentially the same thing: One
with, and one without the braces, the difference being the number of
statements (0-1 vs. 0-n). In the compiled code, there IS no semantic
difference - a branch does not care how many statements it skips. Why
should the language differentiate?

In the try/catch/finally case, braces could be "inferred" for all
blocks except the last catch or the finally, because catch and finally
are single-use keywords. But would anyone want to add such complexity
to the compiler to save those few keystrokes?
 
G

George W. Cherry

Henrik S. Hansen said:
Does anyone know why braces are required around a try/catch block of
code? It seems counter-intuitive, since if/else etc. accept a single
statement without braces.

Let me change the question around: why not mandatory
block, {}, in

if (boolean-expression) { doSomething(); }

and

do {
statement or statements
} while (boolean-expression);

and so on? I do this anyway.

George
 
T

Thomas G. Marshall

Bent C Dalager said:
I have seen this bug in production code, and it can be quite
insidious. I only trapped it because I started wondering why the
debugger was jumping around in such a non-conventional manner :)

It wasn't even the bug I was looking for (or so it told me, and waved
its hand ... hmmm). In stead, it was a latent bug that would show up
one time out of a million and do something slightly wrong. But not
sufficiently wrong that anyone had cried up about it. Yet.

Yeah, but that's not enough.

A language cannot attempt to solve all manner of bugs at the price of lost
readability.

Here's a bug too:

a = a++;

I've seen that from time to time in C land (ages ago), and I hardly ever saw
compilers even warn about that. Should that necessitate the abolishion of
the unary ++ operator?

You have to draw the line somewhere. I like where Java's drawn that line.
No MI. Labeled (downward) break (goto). So far so good, but I'm worried
about the future. For example, I'm holding my breath that the
auto-boxing/unboxing of primitives in 1.5 doesn't swim up and bite us all in
the ass.
 
C

Chris Smith

Bent said:
I have seen this bug in production code, and it can be quite
insidious. I only trapped it because I started wondering why the
debugger was jumping around in such a non-conventional manner :)

Really, though, you have to ask yourself a very important question: if
someone doesn't have the basic understanding of the language to avoid
this, is their code worth using anyway. If it weren't for office-
political considerations, programmers who lack such basic understanding
of the language they are working in should be asked to stay home for the
good of the project. They certainly can't be trusted to be diligent
about introducing really difficult bugs.

Real bugs introduced by competent programmers have to do with making
wrong assumptions about code that's being written, not failing to
understand a basic point of language syntax. No language feature in the
world could have prevented the programmer in question from introducing
some kind of bug that ost you that productivity.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Shripathi said:
But only if you assume the try and if to be similar in all respects with
respect to the single statement.

A try must be followed by a catch, an if has no such restrictions.

In that sense, it is more along the lines of a do { ...} while (...);
statement.

I think that try { .. } catch(...) {}... is best compared to that.

Okay, fine. So it's a syntax error equivalent to:

do
statement1;
statement2;
while (...);

So while you managed to point out one possible difference between if and
try, it was not relevant to what was being discussed.

Besides which, a try does not need to be followed by a catch. It needs
to be followed by one or more catch blocks and/or exactly one finally
block.
If the constructs were similar, perhaps yes. If they are not, it cannot be.
An if may have a else clause, whereas a try must. It is not reasonable to
expect the two to have identical syntax.

Whether "identical" is the right word, it does make sense to build the
entire language upon one set of syntactical onstructs. To require a
compound statement in some places while allowing either type of
statement in others is a needless complication of the language, and is
really somewhat pointless. So I agree that either form should be usable
in either case.

I also think ANYTHING that makes small try blocks less syntactically
intrusive is a good thing. As it is, programmers write horrible code
just because better code is really ugly.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Tor Iver Wilhelmsen

Thomas G. Marshall said:
Using your logic there shouldn't be any literals per se. Everything should
be single element arrays for literals.

int[] a = {1};
a[0]++;

What does arrays have to do with statement blocks? I cannot see how
this follows at all.
The answer is that there is /no/ reason for a language to be
consistant to the extent that readability suffers.

Readability *suffers* when there are mutiple ways of expressing the
same thing.
You need only one of while, for, do loops, so why all three?

Readability. And readability over the lifecycle of a product directly
influences maintainability.

But a for-loop isn't readable. :)
 
J

Joona I Palaste

Really, though, you have to ask yourself a very important question: if
someone doesn't have the basic understanding of the language to avoid
this, is their code worth using anyway. If it weren't for office-
political considerations, programmers who lack such basic understanding
of the language they are working in should be asked to stay home for the
good of the project. They certainly can't be trusted to be diligent
about introducing really difficult bugs.
Real bugs introduced by competent programmers have to do with making
wrong assumptions about code that's being written, not failing to
understand a basic point of language syntax. No language feature in the
world could have prevented the programmer in question from introducing
some kind of bug that ost you that productivity.

I have seen this sort of thing in production code:

public void addAttribute(HttpServletRequest request, String attrName,
String attrValue) {
List list = (List)request.getAttribute(attrName);
list.add(attrValue);
request.setAttribute(attrName, list);
}

The funny part is the third line. The programmer thought that because
the object the reference points to has undergone an internal state
change, the reference would somehow be invalidated. It seems that the
programmer has the design clearly figured out, he just doesn't
understand the implementation language.

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"It's time, it's time, it's time to dump the slime!"
- Dr. Dante
 
B

Bent C Dalager

If it weren't for office-
political considerations, programmers who lack such basic understanding
of the language they are working in should be asked to stay home for the
good of the project.

I have no reason to believe that whoever introduced the error was
incompetent so your argument doesn't really hold. In my experience,
very competent programmers can easily introduce errors just like that
one.

Personally, I would like a language that didn't depend on programmers
being flawless. The more trivial errors it can either catch or
completely do away with, the better.

Cheers
Bent D
 
C

Chris Smith

Bent said:
I have no reason to believe that whoever introduced the error was
incompetent so your argument doesn't really hold. In my experience,
very competent programmers can easily introduce errors just like that
one.

I guess your experience differs from mine. I understand programmers
introducing bugs; heck, I've done quite enough of that. What I don't
understand is introducing bugs that don't result from not paying
attention, but rather from being completely non-sensical. Seems obvious
to me that someone who actually knows Java would just as soon start
capitalizing all their keywords and reversing the order of statements in
a for loop as write code like that.

Again, there is a cost for restrictions like requiring braces. That
cost is that very quick simple statements are suddenly required to take
up something like four lines of code (depending on style) when they
could have taken one. The one-line looks like what it is: a quick
conditional statement. The four-line version does the same thing, but
looks like a huge production of some sort, and misleads the reader.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Thomas G. Marshall

Shripathi Kamath said:
But only if you assume the try and if to be similar in all respects
with respect to the single statement.

A try must be followed by a catch, an if has no such restrictions.

In that sense, it is more along the lines of a do { ...} while (...);
statement.

As I thought too, but

do
gurgleSpitSplat();
while (sick)

is possible.
 
T

Thomas G. Marshall

As I thought too, but

do
gurgleSpitSplat();
while (sick)

is possible.

But you're right on that account entirely, sorry. The do /requires/ a while
in propper proximity.
 
J

Jos A. Horsmeier

Shripathi Kamath said:
Maybe you can stop wondering if I explained it with the braces:

Whether you write a statement as

if (b) {
s1;
}

or

if (b)
s1;

or

if (b) s1;

A compiler wouldn't care about the brace.


Likewise if a similar syntax were allowed for try .. catch (and to be clear,
it is not today) then

try {
s1;
} catch (Exception e) {}

or

try
s1;
catch (Exception e) ;

or

try s1; catch (Exception e) ;

the compiler wouldn't care, either.


The readability or the code (or lack thereof) notwithstanding, it is the
same code, not any poorer.

It doesn't work that way. The do ... while() construct ruins your reasoning.
Have a look at this:

do try s1; while (<very long conditional>); // #1
catch (Exception e); while (<something>);

only at location '#1' the compiler is able to figure out that something
fishy is going on, and it can't decide what to do ... It's much safer to
add the curly brackets (LALR(1) parsers aren't psychic) although those
brackets look like syntactic sugar.

kind regards,

Jos
 
D

Dale King

Jacob said:
In 15 years of C++ and Java I have never made
such an error. My editor (emacs) will reindent
code immediately, and the lack of braces whould
become immediately apparent.


In my almost 20 years of C, C++ and Java I'm not sure I have made that error
either although I agree with Tor and always use braces without exception.

I did however once commit this error:

while( someCondition );
{
doSomething();
}

In case you missed it, the error is the semicolon at the end of the while
statement. That error cost me over a week of development time on a project
that was under the gun. If braces were always required I could not have made
that error.
 
E

EJP

Joona said:
I have seen this sort of thing in production code:

public void addAttribute(HttpServletRequest request, String attrName,
String attrValue) {
List list = (List)request.getAttribute(attrName);
list.add(attrValue);
request.setAttribute(attrName, list);
}

The funny part is the third line. The programmer thought that because
the object the reference points to has undergone an internal state
change, the reference would somehow be invalidated. It seems that the
programmer has the design clearly figured out, he just doesn't
understand the implementation language.

It doesn't just depend on the language, it depends on the API too. The
image codec/decodec classes require you to call the setWriteParam method
in a similar pattern to the above, because the getWriteParam method
returns a clone of the object, not the original.

EJP
 
D

Dario

If you have not braces how do you interpret the following code:

try
s1();
catch(Exception e1)
try
s2();
catch(Exception e2)
s3();
catch(Exception e12)
s12();

as the following?

try {
s1();
}
catch(Exception e1) {
try {
s2();
}
catch(Exception e2) {
s3();
}
}
catch(Exception e12) {
s12();
}

or as the following?

try {
s1();
}
catch(Exception e1) {
try {
s2();
}
catch(Exception e2) {
s3();
}
catch(Exception e12) {
s12();
}
}

This is why LALR(1) parsers are involved!

See <http://makeashorterlink.com/?D11A62785>
and finally stop this thread!

- Dario
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top