Exception handling in C - making try catch work across functions - c

I am writing an exception handling library in C and i ran into a bump:
#define TRY do{ jmp_buf ex_buf__; switch( setjmp(ex_buf__) ){ case 0:
#define FINALLY break; } default:
#define CATCH(x) break; case x:
#define ETRY } }while(0)
#define THROW(x) longjmp(ex_buf__, x)
In my current implementation of try catch throw, I won't be able to throw an exception from inside a method called from inside the try block because the jmp_buf variable is local. How would i make that possible?
I thought about a global variable but that would not allow me to have nested try catch blocks.

You need to use a global jump buffer, because it needs to be visible to your "clients". You could, for example, save the old jump buffer in a try block, and restore it after its use.
In general, I would not recommend this approach at all, though. Trying to retrofit features into a language is fraught with peril, not the least of which would be the following code:
for ;; {
TRY {
if (someVar) {
break;
}
}
FINALLY {
doIt()
}
ETRY
}

Use a stack of jmp_buf's. Or better yet, use the existing CII library, which has been designed, built, and tested for this purpose.

Related

Best practices for non-local exit with cleanup in C?

What is considered best practice for aborting on errors in C?
In our code base we currently have a pattern using
#define CHECKERROR(code) if(code) { return code; }
but this leads to resources not being closed in code of the form
/* not actual code due to non-disclosure restrictions */
int somefunction() {
handle_t res1, res2;
int errorcode;
res1 = getResource();
res2 = getResource();
errorcode = action1(res1, res2);
CHECK(errorcode);
errorcode = action2(res1, res2);
CHECK(errorcode);
freeResource(res1);
freeResource(res2);
return errorcode;
}
I came across the pattern
/* initialize resources */
do {
/* ... */
errorcode = action();
if(errorcode) break;
/* ... */
} while(0);
/* cleanup resources */
return errorcode;
before in articles, but couldn't find any source discussing it now.
What is a good practice, that would be considered idiomatic to C? Does the do { } while(0); pattern qualify? Is there an idiomatic way to make it more clear, that it is not intended to be a loop, but a block with non-local exit?
What is considered best practice for aborting on errors in C?
What is a good practice, that would be considered idiomatic to C?
Really, nothing. There is no best-practice. Best is to tailor a specific solution to the specific case you are handling. For sure - concentrate on writing readable code.
Let's mention some documents. MISRA 2008 has the following. The rule is strict - single exit point. So you have to assign variables and jump to a single return statement
Rule 6–6–5 (Required) A function shall have a single point of exit at
the end of the function.
Error handling is the only place where using goto is actually encouraged. Linux Kernel Coding style presents and encourages using goto to "keep all exit points close". The style is not enforced - not all kernel functions use this. See Linux kernel coding style # Centralized exiting of functions.
The kernel recommendation of goto was adopted by SEI-C: MEM12-C. Consider using a goto chain when leaving a function on error when using and releasing resources.
Does the do { } while(0); pattern qualify?
Sure, why not. If you do not allocate any more resources inside the do { .. here .. }while(0) block, you might as well write a separate function and then call return from it.
There are also expansions on the idea. Even implementations of exceptions in C using longjmp. I know of ThrowTheSwitch/CException.
Overall, error handling in C is not easy. Handling errors from multiple libraries becomes extremely hard and is an art of its own. See MBed OS error-handling, mbed_error.h, even a site that explains MBed OS error codes.
Strongly prefer single return point from your functions - as you found out, using your CHECK(errorcode); will leak resources. Multiple return places are confusing. Consider using gotos:
int somefunction() {
int errorcode = 0;
handle_t res1 = getResource();
if (!res1) {
errorcode = somethnig;
goto res1_fail;
}
handle_t res2 = getResource();
if (!res2) {
errorcode = somethnig_else;
goto res2_fail;
}
errorcode = action1(res1, res2);
if (!errorcode) {
goto actions_fail;
}
errorcode = action2(res1, res2);
if (!errorcode) {
goto actions_fail;
}
actions_fail:
freeResource(res2);
res2_fail:
freeResource(res1);
res1_fail:
return errorcode;
}
First of all, mysterious macros such as your CHECKERROR which hide away flow control are widely considered very bad practice. Don't do that - creating secret macro languages that no other C programmer understands is a much more serious quality concern than code repetition. Code repetition isn't good but it shouldn't be solved by creating a much worse problem. Assume that the reader knows C well, but don't assume that they know or want to know your secret macro language local to this project.
In idiomatic C there are two acceptable ways to write this code. Either with explicit return or with the "on error goto" pattern à la BASIC. I would generally recommend the return version since it saves you from having that old tiresome "goto considered harmful" debate yet again. But goto to a clean-up at the end of the function is acceptable too, as long as you only jump downwards.
(Your do-while(0) with break is just a goto in disguise. It isn't better or worse.)
The single point of return from functions is also debated, especially in the context of MISRA-C (see this). Multiple returns from a function is however fine as long as it doesn't make the code harder to read. In practice this means that you should avoid return (or goto) from inside deeply nested loops or statements. Generally keep the "cyclomatic complexity" (the number of possible execution paths in a function) as low as possible.
In case you need to free up resources, I personally prefer return over goto. For return you need to make a wrapper function, which also serves the purpose of separating resource allocation from the algorithm. I would have rewritten your code like this:
typedef enum // use an actual enum not sloppy int
{
OK, // keeping code 0 for no error is the most common practice
ERR_THIS,
ERR_THAT
} err_t;
static err_t the_actual_algorithm (handle_t res1, handle_t res2) // likely inlined
{
err_t errorcode;
errorcode = action1(res1, res2);
if(errorcode != OK) { return errorcode; }
errorcode = action2(res1, res2);
if(errorcode != OK) { return errorcode; }
return OK;
}
err_t somefunction (void) // note void, not empty parenthesis which is obsolete style
{
handle_t res1, res2;
err_t errorcode;
res1 = getResource();
res2 = getResource();
errorcode = the_actual_algorithm(res1, res2);
freeResource(res1);
freeResource(res2);
return errorcode;
}

How do I write if conditions like these in a macro?

I'm quite new to macros.
I know how to use if condition using ternary operator.
How do I convert this into a #define
if(i==j)
{
count=count+1;
break;
}
I try my luck with this but seems like it is wrong:
#define ifcount(i,j) ((i)==(j)? count=count+1\
break:0)
This is the code i'm trying to convert
http://pastebin.com/i7Tuyh00
Using (abusing) macros to change the flow of the program is usually a bad idea, because the people that will read your code (yourself in a few years) may get surprised by unexpected jumps in the program flow.
That said, your problem has nothing to do with the ternary operator. Actually the ternary operator cannot contain a break in its right side, only expressions.
But macros are allmighty, so you can just do:
#define ifcount(i,j) if ((i)==(j)) { count=count+1; break; }
The main problem with this macro is that people will write a ; when using it, and it will break badly if it is used between another if /else pair, without braces:
if (...)
ifcount(a,b);
else // <--- syntax error because the previous ; breaks the if /else relation
...;
The standard solution is to use the do/while(0) idiom:
#define do { ifcount(i,j) if ((i)==(j)) { count=count+1; break; } } while (0)
But that will not work because the break will break this inner while, not the one you want (credit to #abelenky) below.
The only other C statement that allows a compound statement and ends with a ; is this one:
#define ifcount(i,j) if ((i)==(j)) { count=count+1; break; } else
The problem is that if you forget to add the ; when using ifcount(i,j), instead of a compiler error you will get a silently compiling and surprisingly change in behavior.
I don't see any need to use the ternary (?:) operator.
So here is your macro using an if-statement.
#define IfCount(i,j) if ((i)==(j)) { count++; break; }
Usage:
IfCount(x,5);
Okay, what do you guys think of this?
#define IfCount(i,j) if ((i)==(j)) { count++; break; } do{}while(0)
The final, isolated do-while-0 serves a couple of purposes:
Its a place to hang a semi-colon, so the macro usage looks like "normal" C and ends with a semi-colon.
It prevents an inadvertent else-statement afterwards, because the syntax do{}while(0) else is invalid.
Is there anything else it should take care of?

Practical differences between "do {...} while (0)" and "{...} ((void)0)" in macros?

It's common practice in C to use:
#define FOO() do { /* body */ } while (0)
While this is fine, it's also possible to do:
#define FOO() { /* body */ }((void)0)
{...}((void)0) has many of the same benefits: you can't accidentally merge logic, and a ; is required at the end of the line, so odd expressions like this don't go by un-noticed: FOO() else {...}.
The only difference I've noticed is it means you need to use braces in if-statements.
if (a)
FOO();
else
BAR();
Must be written as:
if (a) {
FOO();
} else {
BAR();
}
Other then this quirk, it seems to work well, preventing the same kinds of problems do/while method is typically used for.
Are there any significant differences between the 2 methods?
Said differently, if you see a code-base using {...}((void)0), are practical reasons to switch to using do{..}while(0), besides the one difference already noted?
The practical difference is exactly what you pointed out.
The do { ... } while (0) idiom means that the macro can be used in any context that requires a statement.
Your suggested idiom { ... } ((void)0) can be used safely in most contexts that require an expression -- but it can fail if it's used in an unbraced if statement.
I can think of no good reason to use an unfamiliar idiom that almost always works, when there's a well known idiom that always works.
One difference is you can use break with #define FOO() do { /* body */ } while (0) but not with #define FOO() { /* body */ }(void)0.
Let's say you are inside a function, say hello(), and doing something in #define FOO() do { /*some device operation */ } while (0) but some error occurred so you no longer want to proceed with that device but there are other statements in function hello() you want to execute, let's say for another device.
So if you use second statement then you will do return most probably which will exit out of hello() but if you use the first statement you can happily break and do some operation in same function hello() for another device.

Purpose of #define foo() do { } while (0)

While browsing sources of LinCAN driver, I found some macros that baffled me.
#else /*CONFIG_PREEMPT*/
#define can_preempt_disable() do { } while (0)
#define can_preempt_enable() do { } while (0)
#endif /*CONFIG_PREEMPT*/
I understand the usefulness of
do {
...;
if(condition) break;
...
} while (0);
using break as a kind of throw. I semi-understand wrapping a sequence of functions like
#define FOO() do { foo(); bar(); } while (0)
to avoid caveats with braceless if. I understand sometimes "no-op statements" are required for a #define. But why this particular kind? specifically, empty braces, false condition, do...while? Some syntax caveats I can't quite grasp?
It is a common syntax for notifying the compiler that macro should be treated as a statement instead of as an expression (statements vs expressions).
In this case compiler will alert you if you try to use can_preempt_disable() as an expression. This means that we forced compile-time check that can_preempt_disable() is used as a statement. Compile-time checks are very often desirable.
The complete passage from the relevant file is:
#if !defined(CONFIG_PREEMPT_RT) && ( defined(CONFIG_PREEMPT) ||
(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) )
#define can_preempt_disable preempt_disable
#define can_preempt_enable preempt_enable
#else /*CONFIG_PREEMPT*/
#define can_preempt_disable() do { } while (0)
#define can_preempt_enable() do { } while (0)
#endif /*CONFIG_PREEMPT*/
Thus, the first part is the code you get when you've asked for pre-emption protection, otherwise you get the empty, do-nothing, loops.
I guess they're written like that for the usual reasons, i.e. to ensure that the macro still is a valid statement.
There shouldn't be a terminating semicolon in the definition, since that will be in the code using these, such as this function which begins:
int c_can_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
{
can_preempt_disable();
...
So, clearly the macro is used like any other function call, and the semicolon is right there where the macro is invoked. This is very normal.
UPDATE 2: Defining it to a ; leads to double semicolons which is ugly, at least in my opinion. An empty brace pair {} would work I guess, but this do/while construct is even more idiomatic since it's often used in cases like these.
UPDATE 3: As pointed out in a comment, an empty brace pair won't work since then you can't put a semicolon after the call. Aah. Thanks!

Why is this construct used? Mad or genius?

I'm working with a large SDK codebase glommed together from various sources of varying quality / competence / sanity from Linus Torvalds to unidentified Elbonian code slaves.
There are an assortment of styles of code, some clearly better than others, and it's proving an interesting opportunity to expand my knowledge / despair for the future of humanity in alternate measures.
I've just come across a pile of functions which repeatedly use a slightly odd (to me) style, namely:
void do_thing(foo)
{
do {
if(this_works(foo) != success)
break;
return(yeah_cool);
} while (0);
return(failure_shame_death);
}
There's nothing complicated being done in this code (I haven't cut 10,000 lines of wizardry out for this post), they could just as easily do:
if(this_works(foo) == success)
return(yeah_cool);
else
return(failure_shame_death);
Which would seem somehow nicer / neater / more intuitive / easier to read.
So I'm now wondering if there is some (good) reason for doing it the other way, or is it just the way they always do it in the Elbonian Code Mines?
Edit: As per the "possible duplicate" links, this code is not pre-processed in any sort of macro, it is just in the normal code. I can believe it might be due to a coding style rule about error checking, as per this answer.
Another guess: maybe you didn't quote the original code correctly? I have seen the same pattern used by people who want to avoid goto: they use a do-while(0) loop which at the end returns a success value. They can also break out of the loop for the error handling:
int doXandY() {
do {
if (!x()) {
break;
}
if (!y()) {
break;
}
return 0;
} while( 0 );
/* Error handling code goes here. */
globalErrorFlag = 12345;
return -1;
}
In your example there's not much point to it because the loop is very short (i.e. just one error case) and the error handling code is just a return, but I suspect that in the real code it can be more complex.
Some people use the do{} while(0); construct with break; inside the loop to be compliant in some way with MISRA rule 14.7. This rule says that there can be only single enter and exit point in the function. This rule is also required by safety norm ISO26262. Please find an example function:
int32_t MODULE_some_function(bool first_condition,bool second_condition)
{
int32_t ret = -1 ;
do
{
if(first_condition)
{
ret = 0 ;
break ;
}
/* some code here */
if(second_condition)
{
ret = 0 ;
break ;
}
/* some code here */
} while(0) ;
return ret ;
}
Please note however that such a construct as I show above violates different MISRA rule which is rule 14.6. Writing such a code you are going to be compliant with one MISRA rule, and as far as I know people use such a construct as workaround against using multiple returns from function.
In my opinion practical usage of the do{}while(0); construct truely exist in the way you should construct some types of macros.Please check below question, it was very helpful for me :
Why use apparently meaningless do-while and if-else statements in macros?
It's worth notice also that in some cases do{}while(0); construct is going to be completely optimized away if you compile your code with proper optimization option.
Hm, the code might be preprocessed somehow. The do { } while(0) is a trick used in preprocessor macros; you can define them like this:
#define some_macro(a) do { whatever(); } while(0)
The advantage being that you can use them anywhere, because it is allowed to put a semicolon after the while(0), like in your code above.
The reason for this is that if you write
#define some_macro(a) { whatever(); }
if (some_condition)
some_macro(123);
else
printf("this can cause problems\n");
Since there is an extra semicolon before the else statement, this code is invalid. The do { ... } while(0) will work anywhere.
do {...} while(0) arranged with "break" is some kind of "RAII for Plain C".
Here, "break" is treated as abnormal scope exit (kind of "Plain C exceptions"), so you can be sure that there is only one place to deallocate a resource: after a "while(0)". It seems slightly unusual, but actually it's very common idiom in the world of plain C.
I would guess that this code was originally written with gotos for error handling:
void do_thing(foo)
{
if(this_works(foo) != success)
goto error;
return(yeah_cool);
error:
return(failure_shame_death);
}
But at some point an edict came down from on high "thou shalt not use goto", so someone did a semi-automatic translation from goto style to loop-break style (perhaps with simple script). Probably when the code was merged/moved from one project to another.

Resources