I then rather too hastily abandoned this attempt under the impression that the curly braces are an essential part of the switch statement merely because that's how everyone shows them.
As I read further macro tricks I came across the blog of Jens Gusted, author of the unfortunately QT licensed P99 macro set which provides excellent capabilities, including try, catch and except in the syntax form I was seeking which does not involve trailing macros.
So I took a look at how Jens managed it and noticed a few tricks, including use of for (type var=...;...;...) as a way to start an indefinitely chainable single-statement scope that did not need a close-curly-brace but could declare a variable for that scope. But what most caught my eye was his use of the switch statement without curly braces.
It soon became apparent that the switch statement is just a statement, and that the case clauses are merely goto-label placeholders. Curly braces are normally used in switch to form multiple statements into a compound statement.
So if I can express my try and finally/except blocks without the need for me to provide curly braces, there will be no need for me to supply a close-brace.
An examples of brace-less switch statement:
http://stackoverflow.com/questions/8118009/is-there-a-useful-case-using-a-switch-statement-without-braces
switch (x)
default:
if (prime(x))
case 2: case 3: case 5: case 7:
process_prime(x);
else
case 4: case 6: case 8: case 9: case 10:
process_composite(x);
and blessed day, as Johan Bezem shows further on that page, it allows you to start part-way through a loop, avoiding the continuation test on entry - that is useful!
uint8_t counter;
/* counter will get its value here somewhere */
switch (counter)
default:
while (0 < counter)
{
case 0:
/* Perform action */
counter--;
}
Also, some people prefer switch(0) default: ... instead of do { ... } while(0) but Jens prefers if (1) { ... } else (void(0))
Try Again
So I repeat my switch based attempt, the parts in bold are provided by the macros:for(jmp_buf active_jmp_buf; ...; ...)
switch ((errno=setjmp(active_jmp_buf)))
if (0) {
case 0: // first time around
{
...
... throw(123);
...
}
break; } else default: // break not needed for finally
{
...
}
Note that the if/else is bogus, merely a trick to hold two statements without using curly braces to denote a compound statement; although I took care to make it if (0) in order to get legitimate fall-through from the try branch into the finally branch.
I need to finish the for loop so that it only loops once, and perhaps include an extra single-case switch statement within each branch so that misplaced break directives will not affect our exception handling switch statement.
I also wonder if I can have multiple catch clauses like the C# except clauses or if I embed those within a single except clause with an explicit switch statement based on errno.
No comments:
Post a Comment