Thread: The new try/catch macros

The new try/catch macros

From
Thomas Hallgren
Date:
As I was integrating the new PG_TRY/PG_CATCH/PG_END_TRY macros I 
discovered a couple of minor issues.

1. You use a do {...} while(0) construct to wrap the whole thing. This 
actually makes it impossible to write code that does a try/catch within 
a loop that contains code surrounding it since a continue or break will 
then end up in the wrong place.

2. There's no PG_TRY_RETURN(x) or PG_TRY_RETURN_VOID() macros. Such 
macros are useful when you wish to do a return from within a try/catch. 
Correcting #1 to not use do {...} while(0) it would also be beneficial 
to add PG_TRY_CONTINUE and PG_TRY_BREAK to be able to break out of a 
loop surrounding the try/catch block.

3. IMHO, it's a bit ugly to require parenthesis and semicolons at the 
end of the macros. They are not normally functions (in most languages, 
there are no parenthesis or semicolon except for the catch clause where 
you can define the actual exception variable)

IMHO, you could just remove the do at the beginning and while(0) at the 
end, and add a semicolon to the PT_TRY and PG_CATCH macros to get rid of 
the incorrect continue/break behaviour and normalize the macros somewhat 
so you'd get:

#define PG_TRY_CATCH_POP \    PG_exception_stack = save_exception_stack; \    error_context_stack =
save_context_stack;

#define PG_TRY  \    { \        sigjmp_buf *save_exception_stack = PG_exception_stack; \        ErrorContextCallback
*save_context_stack= error_context_stack;\        sigjmp_buf local_sigjmp_buf; \        if (sigsetjmp(local_sigjmp_buf,
1)== 0) \        { \            PG_exception_stack = &local_sigjmp_buf;
 

#define PG_CATCH  \            PG_TRY_CATCH_POP \        } else { \            PG_TRY_CATCH_POP

#define PG_END_TRY  \        } \    }

#define PG_TRY_CONTINUE { PG_TRY_CATCH_POP continue; }
#define PG_TRY_BREAK { PG_TRY_CATCH_POP break; }
#define PG_TRY_RETURN_VOID { PG_TRY_CATCH_POP return; }
#define PG_TRY_RETURN(x) { PG_TRY_CATCH_POP return (x); }

Now you write things like

PG_TRY
{    ...
}
PG_CATCH
{    ...
}
PG_END_TRY

Loops etc. will be possible to using the PG_TRY_BREAK/PG_TRY_CONTINUE

Thoughts?

Regards,

Thomas Hallgren



Re: The new try/catch macros

From
Tom Lane
Date:
Thomas Hallgren <thhal@mailblocks.com> writes:
> 1. You use a do {...} while(0) construct to wrap the whole thing. This 
> actually makes it impossible to write code that does a try/catch within 
> a loop that contains code surrounding it since a continue or break will 
> then end up in the wrong place.

A continue or break exiting the construct would do the wrong thing
anyway, so I don't see that removing the do{} is very helpful.  The
point of having it is to make sure that a try/end try block is
syntactically like a statement, rather than like a { ... } construct.

> 3. IMHO, it's a bit ugly to require parenthesis and semicolons at the 
> end of the macros.

This isn't really open for debate, because if we don't put that there,
pg_indent will go nuts.
        regards, tom lane


Re: The new try/catch macros

From
Thomas Hallgren
Date:
Tom Lane wrote:
> A continue or break exiting the construct would do the wrong thing
> anyway, so I don't see that removing the do{} is very helpful.  The
> point of having it is to make sure that a try/end try block is
> syntactically like a statement, rather than like a { ... } construct.
>
Yes, a continue or break would fail. A PG_TRY_BREAK or PG_TRY_CONTINUE 
(as per my suggestion) would however work just fine.

And, you get a statement syntax anyway since you can do it all within 
one single if/else (i.e. with the PG_END_TRY as two ending braces only).

> This isn't really open for debate, because if we don't put that there,
> pg_indent will go nuts.
>
I'm not familiar with pg_indent but my guess is that the first and 
foremost motivation for its existence is code readability and consistent 
style? It must be simple to make it recognize and handle the new macros.  I volunteer to fix that if such a patch would
bewell received.
 

Regards,

Thomas Hallgren



Re: The new try/catch macros

From
Tom Lane
Date:
Thomas Hallgren <thhal@mailblocks.com> writes:
> Tom Lane wrote:
>> This isn't really open for debate, because if we don't put that there,
>> pg_indent will go nuts.
>> 
> I'm not familiar with pg_indent but my guess is that the first and 
> foremost motivation for its existence is code readability and consistent 
> style? It must be simple to make it recognize and handle the new macros. 

Perhaps, but what about everyone's editors' autoindent logic?

I'd have preferred not to have the "();" decoration too, but it is
really not worth the pain.
        regards, tom lane


Re: The new try/catch macros

From
Thomas Hallgren
Date:
Tom Lane wrote:
> Perhaps, but what about everyone's editors' autoindent logic?
> 
> I'd have preferred not to have the "();" decoration too, but it is
> really not worth the pain.
> 
I guess you have a point. Ok, I'll live with it.

Regards,

Thomas Hallgren


Re: The new try/catch macros

From
Bruce Momjian
Date:
Tom Lane wrote:
> Thomas Hallgren <thhal@mailblocks.com> writes:
> > 1. You use a do {...} while(0) construct to wrap the whole thing. This 
> > actually makes it impossible to write code that does a try/catch within 
> > a loop that contains code surrounding it since a continue or break will 
> > then end up in the wrong place.
> 
> A continue or break exiting the construct would do the wrong thing
> anyway, so I don't see that removing the do{} is very helpful.  The
> point of having it is to make sure that a try/end try block is
> syntactically like a statement, rather than like a { ... } construct.
> 
> > 3. IMHO, it's a bit ugly to require parenthesis and semicolons at the 
> > end of the macros.
> 
> This isn't really open for debate, because if we don't put that there,
> pg_indent will go nuts.
> 

Could we just teach pgindent about these macros?

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
359-1001+  If your life is a hard drive,     |  13 Roberts Road +  Christ can be your backup.        |  Newtown Square,
Pennsylvania19073