Thread: The new try/catch macros
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
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
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
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
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
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