why must return statement precede a throw statement in a catch block
You are wrong: both your examples raise the Dead code compiler error because both throw
and return
mark the exit point of a method and no further code is allowed beyond that point.
However, whether the compiler allows it or not, the code below either the throw
or the return
is still dead and will never get a chance to execute.
(NOTE: this question was initially tagged as Java and my first sentence pertains to Java compiler semantics)
return
will exit the method; throw
will also exit the method, assuming it is not inside the try
. It can only exit once!
So regardless of the order - the first of the throw
/ return
effectively end the method.
As more general feedback, though: if the intent is to return false upon failure, all you need is:
try
{
session.Save(obj);
return true;
}
catch
{
return false;
}
Personally, I would say that this is bad code - it hides the actual problem from the caller, making it very hard to debug. It tells us nothing of why it failed. I would say that the better approach is simply to let the exception bubble. In that case, there is no point returning true
, because we would never return false
- and there is no point catching an exception just to re-throw it. So the entire method becomes:
session.Save(obj);
(nothing else required whatsoever)
If your question is "why does only one of these generate a warning": a fair question, but the compiler isn't required to spot either of them for you. Perhaps it should spot it. I suspect that gmcs
would spot this and warn about it - the compiler in mono is far more willing to point out stupidity.
Edit: as expected, [g]mcs outputs:
Program.cs(15,13): warning CS0162: Unreachable code detected
Program.cs(28,13): warning CS0162: Unreachable code detected
for the code below - so it does indeed report both uses as warnings:
class Program
{
static void Main() { }
static void DoSomething() { }
bool ReturnFirst()
{
try
{
DoSomething();
return true;
}
catch
{
return false;
throw; // line 15
}
}
bool ThrowFirst()
{
try
{
DoSomething();
return true;
}
catch
{
throw;
return false; // line 28
}
}
}