| Thread overview | |||||||||
|---|---|---|---|---|---|---|---|---|---|
|
March 07, 2007 Return in finally | ||||
|---|---|---|---|---|
| ||||
While programatically porting Java ...
A finally block cannot contain another try/catch block. This is allowed in Java. The solution i use is this:
int f(){
try{
} finally {
(){ // start definition of an unnamed function literal
try{
} finally {
// (1)
}
}(); // call it.
}
return 1;
}
Now, i have the first time the situation where at (1) a return statement
occurs. This is not allowed in an a finally block at all [2], and
withing the function literal it would not end the surrounding function.
Any idea, how to simulate
1.) try/catch/finally in a finally
2.) make a return from within a finally
??
[2] not allowed in D, but it is allowed in Java
| ||||
March 07, 2007 Re: Return in finally | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit (keinfarbton) | Frank Benoit (keinfarbton) wrote:
> While programatically porting Java ...
>
> A finally block cannot contain another try/catch block. This is allowed
> in Java. The solution i use is this:
>
> int f(){
> try{
> } finally {
> (){ // start definition of an unnamed function literal
> try{
> } finally {
> // (1)
> }
> }(); // call it.
> }
> return 1;
> }
>
> Now, i have the first time the situation where at (1) a return statement
> occurs. This is not allowed in an a finally block at all [2], and
> withing the function literal it would not end the surrounding function.
>
> Any idea, how to simulate
> 1.) try/catch/finally in a finally
> 2.) make a return from within a finally
> ??
>
>
> [2] not allowed in D, but it is allowed in Java
try
{
...
}
finally
{
...
return;
...
}
|
|
v
try
{
...
}
catch(Object e)
{
...
return;
...
throw e;
}
bad practice in hand work, but this is auto gen code.
| |||
March 07, 2007 Re: Return in finally | ||||
|---|---|---|---|---|
| ||||
Posted in reply to BCS | If i understand your idea right...
class FinallyException : Object {} // Special excecption to enter a
finally block.
class Throwable : Exception {} // Base of all Java Exceptions
Now, instead of finally use only catch blocks
catch( FinallyException fe ){
...
}
Hm, i need to think more about it...
The FinallyException can be used to transport a thrown exception
At (1),(2) and (3) a return(val) or throw can happen.
// Java ==========================
try{
// (1)
} catch( IOException e ){
// (2)
} finally {
// (3)
}
// D ==========================
auto fe = new FinallyException();
try{
try{
// (1)
throw fe;
} catch( IOException e ){
try{
// (2)
} catch( Object e ) {
fe.store(e);
throw fe;
}
}
}catch( FinallyException fe ){
// (3)
}
fe.throwIfHasException();
Does this work? oh, my brain hurts :)
Another thought, what about the performance, if an exception is always thrown to reach the "finally" block? is that an issue?
| |||
March 07, 2007 Re: Return in finally | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit (keinfarbton) |
// D ==========================
int func(){
...
{
Tioport_ResultState!(int) tioport_result_001;
try{
try{
// (1)
} catch( IOException e ){
// (2)
}
} catch( Object e ) {
// catch and store for rethrow after Finally_001
tioport_result_001.setException( e );
}
Finally_001:
{
// (3)
}
tioport_result_001.checkException(); // throw if one was stored
return tioport_result_001.get();
}
}
In (1) und (2) replace all "return;" with "goto Finally_001;". "return
expr;" with "{ tioport_result_001.set( expr ); goto Finally_001; }"
If in (3) a return or throw occurs, it hides previous returns/throws,
like java does.
This approach do not throw an exception in normal run.
What do you think?
Do I miss a less complicated way?
| |||
March 07, 2007 Re: Return in finally | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit (keinfarbton) | Frank Benoit (keinfarbton) wrote:
> If i understand your idea right...
>
> class FinallyException : Object {} // Special excecption to enter a
> finally block.
> class Throwable : Exception {} // Base of all Java Exceptions
>
> Now, instead of finally use only catch blocks
>
> catch( FinallyException fe ){
> ...
> }
>
There is no need for special excption types, Object will catch everything. Err. However it won't catch a normal exit.
Fud, It's not quite as clean as I thought.
| |||
March 08, 2007 Re: Return in finally | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit (keinfarbton) | Frank Benoit (keinfarbton) escribió: > Any idea, how to simulate > 2.) make a return from within a finally > ?? Maybe you can do something like this: Java ------------------------------------------------- int func() { try { } finally { return 1; } } ------------------------------------------------- D ------------------------------------------------- import std.boxer; int func() { Box finallyReturn; try { } finally { finallyReturn = box(1); } if (finallyReturn.type !is null) { return unbox!(int)(finallyReturn); } } ------------------------------------------------- You have to be careful, though. After every block that has a return statement you have to proceed only if the box's type is null. For example: Java ------------------------------------------------- int func() { try { } finally { if (someCondition) { return 1; } doSomeStuff(); return 2; } } ------------------------------------------------- D ------------------------------------------------- import std.boxer; int func() { Box finallyReturn; try { } finally { if (someCondition) { finallyReturn = box(1); } if (finallyReturn.type is null) { doSomeStuff(); finallyReturn = box(2); } } if (finallyReturn.type !is null) { return unbox!(int)(finallyReturn); } } ------------------------------------------------- Does this work? | |||
March 08, 2007 Re: Return in finally | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ary Manzana |
> Does this work?
yes, this would handle the return, but it would not allow a second try/catch in the finally block.
What i use now is this:
// D ==========================
int func(){
...
{
bool tioport_stat_set_1;
int tioport_stat_val_1;
Object tioport_stat_exc_1;
try{
try{
// (1)
tryend_1:;
} catch( IOException e ){
// (2)
}
catchend_1:;
} catch( Object e ) {
tioport_stat_exc_1 = e;
}
{
// (3)
}
if(tioport_stat_exc_1 !is null) throw tioport_stat_exc_1;
if(tioport_stat_set_1) return tioport_stat_val_1;
}
}
In (1) und (2) replace all "return expr;" with
{ tioport_stat_set_1 = true;
tioport_stat_val_1 = expr; // if has a return val
goto tryend_1; // or catchend_1
}
Now the finally block is a normal code block.
It is possible to have more try/catch in the finally block.
It is possible to return/throw from the finally block
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply