Use of goto in Linux kernel code makes no sense - c

I was going through the Linux source code and here I stumbled over this function:
static int check_free_space(struct bsd_acct_struct *acct)
{
struct kstatfs sbuf;
if (time_is_after_jiffies(acct->needcheck))
goto out;
/* May block */
if (vfs_statfs(&acct->file->f_path, &sbuf))
goto out;
if (acct->active) {
u64 suspend = sbuf.f_blocks * SUSPEND;
do_div(suspend, 100);
if (sbuf.f_bavail <= suspend) {
acct->active = 0;
pr_info("Process accounting paused\n");
}
} else {
u64 resume = sbuf.f_blocks * RESUME;
do_div(resume, 100);
if (sbuf.f_bavail >= resume) {
acct->active = 1;
pr_info("Process accounting resumed\n");
}
}
acct->needcheck = jiffies + ACCT_TIMEOUT*HZ;
out:
return acct->active;
}
I can't find much sense in Marco's use of goto, especially since it leads to a return statement. Why wasn't the function re-written like this:
static int check_free_space(struct bsd_acct_struct * acct) {
struct kstatfs sbuf;
if (time_is_after_jiffies(acct->needcheck) ||
vfs_statfs( &acct->file->f_path, & sbuf)) {
//latter may block
return acct->active;
}
if (acct->active) {
u64 suspend = sbuf.f_blocks * SUSPEND;
do_div(suspend, 100);
if (sbuf.f_bavail <= suspend) {
acct->active = 0;
pr_info("Process accounting paused\n");
}
} else {
u64 resume = sbuf.f_blocks * RESUME;
do_div(resume, 100);
if (sbuf.f_bavail >= resume) {
acct->active = 1;
pr_info("Process accounting resumed\n");
}
}
acct->needcheck = jiffies + ACCT_TIMEOUT * HZ;
}
I've been taught that goto could indeed be useful if used to break out of a nested loop or for memory cleanup. Neither of this is a case here, so why did Marco go for the gotos? There must be some kind of valid reason, right?

Why wasn't the function re-written like this
The function that you just wrote is invalid. More precisely, if this block is not entered:
if (time_is_after_jiffies(acct->needcheck) ||
vfs_statfs( &acct->file->f_path, & sbuf)) {
vfs_statfs( &acct->file->f_path, & sbuf)) {
//latter may block
return acct->active;
}
Then the function will not be able to do a valid return anywhere else. The code will not even compile.
The purpose of the goto in that particular function is to execute an early return without the need of duplicating the return acct->active; line. This is a pretty common pattern which saves duplicated lines of code and sometimes also reduces the size of the resulting executable.

It's the "single return" principle. Some programmers think it should be obeyed at all times.
The function would work exactly the same if you replaced goto out; with return acct->active; However, let's say you want to do this:
out:
printf("Exiting function check_free_space()\n");
return acct->active;
That becomes a lot easier.
Here is a question about single return: Should a function have only one return statement?

Related

How do I handle errors from cleanup / destroy functions

I am struggeling with cleanup code which returns error codes/objects. Examples on how to cleanup a function usually just call free() at the end or anything not returning an error. But a destroy function of a module could be complex and maybe also return errors. Even close() could return a error although often unchecked.
How do you handle situations like that? Do you just log but ignore the error otherwise, do you return the error code of the *_destroy function at the end? Would you somehow restructure the code? What is the recommended solution here?
Thank you
int moduleA_create(moduleA *handle, int param1, int param2, int param3, int param4);
int moduleA_destroy(moduleA handle);
int moduleB_create(moduleB *handle, const char *param);
int moduleB_destroy(moduleB handle);
int some_function(void) {
int r;
moduleA a;
moduleB b;
r = moduleA_create(&a, 1, 2, 3, 4);
if (r < 0) goto EXIT_A;
r = moduleB_create(&b, "some string");
if (r < 0) goto EXIT_B;
// more code
// this could return error
moduleB_destroy(b);
EXIT_B:
// this could return error
moduleA_destroy(a);
EXIT_A:
return r;
}
Do you just log but ignore the error otherwise, do you return the error code of the *_destroy function at the end? Would you somehow restructure the code? What is the recommended solution here?
It's highly situation-dependent, as, indeed, is error-handling in general. Often, there's not much you can do other than emit messages / different return values, and possibly abort the program.
If the error happens in the context of shutting down the application, as your particular example suggests to me, then I would be inclined to attempt to continue the standard shutdown sequence. A diagnostic message to stderr might be warranted. A non-zero exit status might be warranted. Or not.
For example, I usually just ignore failures to close() / fclose() files that were only read, but I would definitely emit a warning or error message on failing to close a file that the program had created or written to, on account of the possibility that the program's operations on the file might not have actually been carried out as intended.
"Would you somehow restructure the code?"
Rather than using goto with its opportunity for code to be wrong, sequenced progress may require undoing what's been done (as best one can) in exactly the reverse order.
Below is a sketch that demonstrates one "successful" trial run, and one run deliberately coded to fail on the 3rd step. It uses the conditional operator for brevity, and always the return code "-1" from teardown functions. This is just a sketch.
Notice that the progress/teardown function invocations are proximate to one another and that the sequence reverses itself.
This code would, of course, be altered to meet needs. It provides a schema that does not require goto labels to be ordered in code, distant from where they may be "used". This is one alternative to "restructuring the code".
int doPh1R() { puts( "doPh1R" ); return -1; }
int doPh1F() { puts( "doPh1F" ); return 1; }
int doPh2R() { puts( "doPh2R" ); return -1; }
int doPh2F() { puts( "doPh2F" ); return 1; }
int doPh3R() { puts( "doPh3R" ); return -1; }
int doPh3F() {
static bool cond = true;
if( cond ) {
puts( "doPh3F" );
cond = !cond; // boobytrap the next execution
return 1;
}
puts( "doPh3F Error" );
return -1;
}
int doSomething( int trial ) {
enum { done, phase1, phase2, phase3, run };
int dir = 1;
int err = -1; // pessimism
printf( "\tTrial #%d\n", trial );
for( int phase = phase1; phase != done; phase += dir )
switch( phase ) {
case phase1:
dir = dir==1 ? doPh1F() : doPh1R();
break;
case phase2:
dir = dir==1 ? doPh2F() : doPh2R();
break;
case phase3:
dir = dir==1 ? doPh3F() : doPh3R();
break;
case run:
puts( "run" );
dir = -1;
err = 0;
break;
}
return err;
}
int main() {
puts( doSomething(1) ? "\tFail" : "\tSuccess" ); // One good run
puts( doSomething(2) ? "\tFail" : "\tSuccess" ); // One bad run
return 0;
}
Output
Trial #1
doPh1F
doPh2F
doPh3F
run
doPh3R
doPh2R
doPh1R
Success
Trial #2
doPh1F
doPh2F
doPh3F Error
doPh2R
doPh1R
Fail

What are some good ways of handling errors (cleanup and abort) in a function that initializes multiple resources in C?

First of all, if someone can reword the question to make it clearer, please do.
A common occurrence in C programming is having several resources to be initialized/allocated in a specific order. Each resource is a prerequisite for the initialization of subsequent ones. If one of the steps fails, the leftover resources from previous steps must be de-allocated. Ideal pseudocode (utilizing a magically generic pure-unobtainium clean_up_and_abort() function) would look approximately as follows:
err=alloc_a()
if(err)
clean_up_and_abort()
err=alloc_b()
if(err)
clean_up_and_abort()
err=alloc_c()
if(err)
clean_up_and_abort()
// ...
profit()
I have seen several ways of handling this, all of them seem to have significant drawbacks, at least in terms of what people tend to consider "good practice".
What is are the most readable and least error-prone ways of structuring the code when handling this situation? Efficiency is preferred, but a reasonable amount of efficiency can be sacrificed for the sake of readability. Please list advantages and drawbacks. Answers discussing multiple methods are welcome.
The goal is to hopefully end up with a set of several preferred methods for solving this problem.
I'll start with some of the methods I've already seen, please comment on them and add others.
The three most common methods I've seen so far:
1: Nested if-statements (without multiple returns for the SESE purists). With a long chain of prerequisites, this gets out of hand fast. IMO, even in simple cases this is a readability disaster and has no real advantages. I am including it because I see people do this (too) often.
uint32_t init_function() {
uint32_t erra, errb, errc, status;
A *a;
B *b;
C *c;
erra = alloc_a(&a);
if(erra) {
status = INIT_FAIL_A;
} else {
errb = alloc_b(&b);
if(errb) {
dealloc_a(&a);
status = INIT_FAIL_B;
} else {
errc = alloc_c();
if(errc) {
dealloc_b(&b);
dealloc_a(&a);
status = INIT_FAIL_C;
} else {
profit(a,b,c);
status = INIT_SUCCESS;
}
}
}
// Single return.
return status;
}
2: Multiple returns. This is my preferred method right now. THe logic is easy to follow but it's still dangerous because cleanup code has to be duplicated and it's easy to forget to deallocate something in one of the cleanup sections.
uint32_t init_function() {
uint32_t err;
A *a;
B *b;
C *c;
err = alloc_a(&a);
if(err) {
return INIT_FAIL_A;
}
err = alloc_b(&b);
if(err) {
dealloc_a(&a);
return INIT_FAIL_B;
}
err = alloc_c(&c);
if(err) {
dealloc_b(&b);
dealloc_a(&a);
return INIT_FAIL_C;
}
profit(a,b,c);
return INIT_SUCCESS;
}
3: GOTO. Many people don't like goto on principle, but this is one of the standard arguments for a valid use of goto in C programming. The advantage is that it's hard to forget a cleanup step and there is no copypasting.
uint32_t init_function() {
uint32_t status;
uint32_t err;
A *a;
B *b;
C *c;
err = alloc_a(&a);
if(err) {
status = INIT_FAIL_A;
goto LBL_FAIL_A;
}
err = alloc_b(&b);
if(err) {
status = INIT_FAIL_B;
goto LBL_FAIL_B;
}
err = alloc_c(&c);
if(err) {
status = INIT_FAIL_C;
goto LBL_FAIL_C;
}
profit(a,b,c);
status = INIT_SUCCESS;
goto LBL_SUCCESS;
LBL_FAIL_C:
dealloc_b(&b);
LBL_FAIL_B:
dealloc_a(&a);
LBL_FAIL_A:
LBL_SUCCESS:
return status;
}
Anything else I did not mention?
4: Global variables, woohoo!!! Because everybody loves global variables, just like they love goto. But seriously, if you limit the scope of the variables to file scope (using the static keyword) then it's not that bad. Side note: the cleanup function takes/returns the error code unchanged, so as to declutter the code in the init_function.
static A *a = NULL;
static B *b = NULL;
static C *c = NULL;
uint32_t cleanup( uint32_t errcode )
{
if ( c )
dealloc_c(&c);
if ( b )
dealloc_b(&b);
if ( a )
dealloc_a(&a);
return errcode;
}
uint32_t init_function( void )
{
if ( alloc_a(&a) != SUCCESS )
return cleanup(INIT_FAIL_A);
if ( alloc_b(&b) != SUCCESS )
return cleanup(INIT_FAIL_B);
if ( alloc_c(&c) != SUCCESS )
return cleanup(INIT_FAIL_C);
profit(a,b,c);
return INIT_SUCCESS;
}
5: Faux OOP. For those who can't handle the truth (that global variables are actually useful in C programs), you can take the C++ approach. C++ takes all of the global variables, puts them into a structure, and calls them "member" variables. And somehow that makes everybody happy.
The trick is to pass a pointer to the structure to all of the functions, as the first argument. C++ does this behind the scenes, in C you have to do it explicitly. I call the pointer that so as to avoid conflicts/confusion with this.
// define a class (uhm, struct) with status, a cleanup method, and other stuff as needed
typedef struct stResources
{
char *status;
A *a;
B *b;
C *c;
void (*cleanup)(struct stResources *that);
}
stResources;
// the cleanup method frees all resources, and frees the struct
void cleanup( stResources *that )
{
if ( that->c )
dealloc_c( &that->c );
if ( that->b )
dealloc_b( &that->b );
if ( that->a )
dealloc_a( &that->a );
free( that );
}
// the init function returns a pointer to the struct, or NULL if the calloc fails
// the status member variable indicates whether initialization succeeded, NULL is success
stResources *init_function( void )
{
stResources *that = calloc( 1, sizeof(stResources) );
if ( !that )
return NULL;
that->cleanup = cleanup;
that->status = "Item A is out to lunch";
if ( alloc_a( &that->a ) != SUCCESS )
return that;
that->status = "Item B is never available when you need it";
if ( alloc_b( &that->b ) != SUCCESS )
return that;
that->status = "Item C is being hogged by some other process";
if ( alloc_c( &that->c ) != SUCCESS )
return that;
that->status = NULL; // NULL is success
return that;
}
int main( void )
{
// create the resources
stResources *resources = init_function();
// use the resources
if ( !resources )
printf( "Buy more memory already\n" );
else if ( resources->status != NULL )
printf( "Uhm yeah, so here's the deal: %s\n", resources->status );
else
profit( resources->a, resources->b, resources->c );
// free the resources
if ( resources )
resources->cleanup( resources );
}
6. setjmp() and longjmp() for simulating exceptions and scoped flow control.
Please don’t do this.

Readable conditional logic without unnecessary execution?

I'm trying to make the below code both readable and performant. I want to avoid any unnecessary call to getFlagB() while also not repeating anything. Below I have written two methods, each which satisfies exactly one of these criteria.
Assume getFlagB() cannot be altered in any way. Is there a way to meet both these requirements simultaneously in C, without creating additional flags?
// Method 1 - doesn't repeat code blocks but calls getFlagB even when it may not need to
void foo(int flagA)
{
int flagB;
getFlagB(&flagB);
if(flagA & flagB)
{
// Code block 0
}
else
{
// Code block 1
}
}
// Method 2 - doesn't no extra call to getFlagB, but repeats code block 1
void foo(int flagA)
{
int flagB;
if(flagA)
{
getFlagB(&flagB);
if(flagB)
{
// Code block 0
}
else
{
// Code block 1
}
}
else
{
// Code block 1
}
}
You can do this:
void foo(int flagA)
{
int flagB;
if(flagA)
{
getFlagB(&flagB);
if(flagB)
{
// Code block 0
return ;
}
}
// code block 1
}
Wrap getFlagB() in another method, then let the compiler sort it out for you.
int myGetFlagB() { int b; getFlagB(&b); return b; }
void foo(int flagA)
{
/* note: assume you mean && and not &, otherwise there is no way
* to short circuit - you always need to call getFlagB for a
* bitwise AND.
*/
if(flagA && myGetFlagB())
{
// Code block 0
}
else
{
// Code block 1
}
}
Compute the condition explicitly before the if.
_Bool condition = flagA;
if ( flagA ) { /* First decide what to do. */
_Bool flagB;
GetFlagB( & flagB );
condition = flagA && flagB; /* Prefer && over &. */
}
if ( condition ) { /* Then do it. */
Code1();
} else {
Code2();
}
If you really do not want to either encapsulate the getFlagB call or split your if, you can abuse the comma operator:
if(flagA && (getFlagB(&flagB), flagB)) {
Even though it does not look nice, it does precisely what you want.
EDIT
You can also do the following, so long as flagB is initialized to 0. This avoids a bug in the code I posted earlier that assumes the flags aren't modified inside code block 0, which can cause both code blocks 0 and 1 to execute. I'd recommend this new one only because you may at some point want to modify the flags inside foo():
int flagB = 0;
if (flagA)
getFlagB(&flagB);
if (flagA && flagB) {
// code block 0
} else {
// code block 1
}
Yes, flagA is tested twice. You have a ternary condition, but you're asking for a binary set of outcomes. Without using sequence points as one person mentioned, you must test twice or duplicate code or unnecessarily call a function or add extra function call overhead if flagA happens to be set.
They're all valid solutions IMHO. It is just a matter of how readable and how well performing you want the code to be, not to mention avoiding code duplication... Nobody likes that! :-)
Happy coding!
I cannot definitively say anything because I have not seen any actual code but it seems to me the flagA is irrelevant and can be ignored. While flagB must be evaluated because it is relevant and causes the code to change.
void foo()
{
getFlagB(&flagB)
if(flagB)
{
//Code 1
}
else
{
//Code 0
}
}
But I am assuming that you do not have an unnecessary flag in your program. So I would recommend doing the seconded one it is more efficient and elegant even thought it does not seem that way.

Is there a better way to do C style error handling?

I'm trying to learn C by writing a simple parser / compiler. So far its been a very enlightening experience, however coming from a strong background in C# I'm having some problems adjusting - in particular to the lack of exceptions.
Now I've read Cleaner, more elegant, and harder to recognize and I agree with every word in that article; In my C# code I avoid throwing exceptions whenever possible, however now that I'm faced with a world where I can't throw exceptions my error handling is completely swamping the otherwise clean and easy-to-read logic of my code.
At the moment I'm writing code which needs to fail fast if there is a problem, and it also potentially deeply nested - I've settled on a error handling pattern whereby "Get" functions return NULL on an error, and other functions return -1 on failure. In both cases the function that fails calls NS_SetError() and so all the calling function needs to do is to clean up and immediately return on a failure.
My issue is that the number of if (Action() < 0) return -1; statements that I have is doing my head in - it's very repetitive and completely obscures the underlying logic. I've ended up creating myself a simple macro to try and improve the situation, for example:
#define NOT_ERROR(X) if ((X) < 0) return -1
int NS_Expression(void)
{
NOT_ERROR(NS_Term());
NOT_ERROR(Emit("MOVE D0, D1\n"));
if (strcmp(current->str, "+") == 0)
{
NOT_ERROR(NS_Add());
}
else if (strcmp(current->str, "-") == 0)
{
NOT_ERROR(NS_Subtract());
}
else
{
NS_SetError("Expected: operator");
return -1;
}
return 0;
}
Each of the functions NS_Term, NS_Add and NS_Subtract do a NS_SetError() and return -1 in the case of an error - its better, but it still feels like I'm abusing macros and doesn't allow for any cleanup (some functions, in particular Get functions that return a pointer, are more complex and require clean-up code to be run).
Overall it just feels like I'm missing something - despite the fact that error handling in this way is supposedly easier to recognize, In many of my functions I'm really struggling to identify whether or not errors are being handled correctly:
Some functions return NULL on an error
Some functions return < 0 on an error
Some functions never produce an error
My functions do a NS_SetError(), but many other functions don't.
Is there a better way that I can structure my functions, or does everyone else also have this problem?
Also is having Get functions (that return a pointer to an object) return NULL on an error a good idea, or is it just confusing my error handling?
It's a bigger problem when you have to repeat the same finalizing code before each return from an error. In such cases it is widely accepted to use goto:
int func ()
{
if (a() < 0) {
goto failure_a;
}
if (b() < 0) {
goto failure_b;
}
if (c() < 0) {
goto failure_c;
}
return SUCCESS;
failure_c:
undo_b();
failure_b:
undo_a();
failure_a:
return FAILURE;
}
You can even create your own macros around this to save you some typing, something like this (I haven't tested this though):
#define CALL(funcname, ...) \
if (funcname(__VA_ARGS__) < 0) { \
goto failure_ ## funcname; \
}
Overall, it is a much cleaner and less redundant approach than the trivial handling:
int func ()
{
if (a() < 0) {
return FAILURE;
}
if (b() < 0) {
undo_a();
return FAILURE;
}
if (c() < 0) {
undo_b();
undo_a();
return FAILURE;
}
return SUCCESS;
}
As an additional hint, I often use chaining to reduce the number of if's in my code:
if (a() < 0 || b() < 0 || c() < 0) {
return FAILURE;
}
Since || is a short-circuit operator, the above would substitute three separate if's. Consider using chaining in a return statement as well:
return (a() < 0 || b() < 0 || c() < 0) ? FAILURE : SUCCESS;
One technique for cleanup is to use an while loop that will never actually iterate. It gives you goto without using goto.
#define NOT_ERROR(x) if ((x) < 0) break;
#define NOT_NULL(x) if ((x) == NULL) break;
// Initialise things that may need to be cleaned up here.
char* somePtr = NULL;
do
{
NOT_NULL(somePtr = malloc(1024));
NOT_ERROR(something(somePtr));
NOT_ERROR(somethingElse(somePtr));
// etc
// if you get here everything's ok.
return somePtr;
}
while (0);
// Something went wrong so clean-up.
free(somePtr);
return NULL;
You lose a level of indentation though.
Edit: I'd like to add that I've nothing against goto, it's just that for the use-case of the questioner he doesn't really need it. There are cases where using goto beats the pants off any other method, but this isn't one of them.
You're probably not going to like to hear this, but the C way to do exceptions is via the goto statement. This is one of the reasons it is in the language.
The other reason is that goto is the natural expression of the implementation of a state machine. What common programming task is best represented by a state machine? A lexical analyzer. Look at the output from lex sometime. Gotos.
So it sounds to me like now is the time for you to get chummy with that parriah of language syntax elements, the goto.
Besides goto, standard C has another construct to handle exceptional flow control setjmp/longjmp. It has the advantage that you can break out of multiply nested control statements more easily than with break as was proposed by someone, and in addition to what goto provides has a status indication that can encode the reason for what went wrong.
Another issue is just the syntax of your construct. It is not a good idea to use a control statement that can inadvertibly be added to. In your case
if (bla) NOT_ERROR(X);
else printf("wow!\n");
would go fundamentally wrong. I'd use something like
#define NOT_ERROR(X) \
if ((X) >= 0) { (void)0; } \
else return -1
instead.
THis must be thought on at least two levels: how your functions interact, and what you do when it breaks.
Most large C frameworks I see always return a status and "return" values by reference (this is the case of the WinAPI and of many C Mac OS APIs). You want to return a bool?
StatusCode FooBar(int a, int b, int c, bool* output);
You want to return a pointer?
StatusCode FooBar(int a, int b, int c, char** output);
Well, you get the idea.
On the calling function's side, the pattern I see the most often is to use a goto statement that points to a cleanup label:
if (statusCode < 0) goto error;
/* snip */
return everythingWentWell;
error:
cleanupResources();
return somethingWentWrong;
What about this?
int NS_Expression(void)
{
int ok = 1;
ok = ok && NS_Term();
ok = ok && Emit("MOVE D0, D1\n");
ok = ok && NS_AddSub();
return ok
}
The short answer is: let your functions return an error code that cannot possibly be a valid value - and always check the return value. For functions returning pointers, this is NULL. For functions returning a non-negative int, it's a negative value, commonly -1, and so on...
If every possible return value is also a valid value, use call-by-reference:
int my_atoi(const char *str, int *val)
{
// convert str to int
// store the result in *val
// return 0 on success, -1 (or any other value except 0) otherwise
}
Checking the return value of every function might seem tedious, but that's the way errors are handled in C. Consider the function nc_dial(). All it does is checking its arguments for validity and making a network connection by calling getaddrinfo(), socket(), setsockopt(), bind()/listen() or connect(), finally freeing unused resources and updating metadata. This could be done in approximately 15 lines. However, the function has nearly 100 lines due to error checking. But that's the way it is in C. Once you get used to it, you can easily mask the error checking in your head.
Furthermore, there's nothing wrong with multiple if (Action() == 0) return -1;. To the contrary: it is usually a sign of a cautious programmer. It's good to be cautious.
And as a final comment: don't use macros for anything but defining values if you can't justify their use while someone is pointing with a gun at your head. More specifically, never use control flow statements in macros: it confuses the shit out of the poor guy who has to maintain your code 5 years after you left the company. There's nothing wrong with if (foo) return -1;. It's simple, clean and obvious to the point that you can't do any better.
Once you drop your tendency to hide control flow in macros, there's really no reason to feel like you're missing something.
A goto statement is the easiest and potentially cleanest way to implement exception style processing. Using a macro makes it easier to read if you include the comparison logic inside the macro args. If you organize the routines to perform normal (i.e. non-error) work and only use the goto on exceptions, it is fairly clean for reading. For example:
/* Exception macro */
#define TRY_EXIT(Cmd) { if (!(Cmd)) {goto EXIT;} }
/* My memory allocator */
char * MyAlloc(int bytes)
{
char * pMem = NULL;
/* Must have a size */
TRY_EXIT( bytes > 0 );
/* Allocation must succeed */
pMem = (char *)malloc(bytes);
TRY_EXIT( pMem != NULL );
/* Initialize memory */
TRY_EXIT( initializeMem(pMem, bytes) != -1 );
/* Success */
return (pMem);
EXIT:
/* Exception: Cleanup and fail */
if (pMem != NULL)
free(pMem);
return (NULL);
}
It never occurred to me to use goto or do { } while(0) for error handling in this way - its pretty neat, however after thinking about it I realised that in many cases I can do the same thing by splitting the function out into two:
int Foo(void)
{
// Initialise things that may need to be cleaned up here.
char* somePtr = malloc(1024);
if (somePtr = NULL)
{
return NULL;
}
if (FooInner(somePtr) < 0)
{
// Something went wrong so clean-up.
free(somePtr);
return NULL;
}
return somePtr;
}
int FooInner(char* somePtr)
{
if (something(somePtr) < 0) return -1;
if (somethingElse(somePtr) < 0) return -1;
// etc
// if you get here everything's ok.
return 0;
}
This does now mean that you get an extra function, but my preference is for many short functions anyway.
After Philips advice I've also decided to avoid using control flow macros as well - its clear enough what is going on as long as you put them on one line.
At the very least Its reassuring to know that I'm not just missing something - everyone else has this problem too! :-)
Use setjmp.
http://en.wikipedia.org/wiki/Setjmp.h
http://aszt.inf.elte.hu/~gsd/halado_cpp/ch02s03.html
http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html
#include <setjmp.h>
#include <stdio.h>
jmp_buf x;
void f()
{
longjmp(x,5); // throw 5;
}
int main()
{
// output of this program is 5.
int i = 0;
if ( (i = setjmp(x)) == 0 )// try{
{
f();
} // } --> end of try{
else // catch(i){
{
switch( i )
{
case 1:
case 2:
default: fprintf( stdout, "error code = %d\n", i); break;
}
} // } --> end of catch(i){
return 0;
}
#include <stdio.h>
#include <setjmp.h>
#define TRY do{ jmp_buf ex_buf__; if( !setjmp(ex_buf__) ){
#define CATCH } else {
#define ETRY } }while(0)
#define THROW longjmp(ex_buf__, 1)
int
main(int argc, char** argv)
{
TRY
{
printf("In Try Statement\n");
THROW;
printf("I do not appear\n");
}
CATCH
{
printf("Got Exception!\n");
}
ETRY;
return 0;
}

Is it possible to execute both if and else part of an if --- else control statement? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Simultaneous execution of both if and else blocks
Is it possible to put some condition, so that both if and else part in an if ...else control statement can be executed without any warning or error ??
Do not use! ;-)
Yes, by forking.
if ( fork() ) {
printf("if\n");
}
else {
printf("else\n");
}
There are no real use cases to prefer the above code, unless it is for parallel execution.
No, there's no way to write a Schrödinger if clause.
You might be able to execute both with a goto, but it would never pass a code review.
Yes, it's possible:
#include <stdio.h>
#define else if (1)
int main(void)
{
int test = 1;
if (test == 1)
{
printf("if\n");
}
else
{
printf("else\n");
}
return 0;
}
#undef else
A note for newbies: Never do this in real life! Instead, think about your problem again...
What you probably wanted is :
#include <stdio.h>
int main(void)
{
int one_condition = 1;
int other_condition = 2;
if ((one_condition == 1) || (other_condition == 2))
{
printf("if\n");
}
if ((one_condition != 1) || (other_condition == 2))
{
printf("quasi-else\n");
}
return 0;
}
You can replace the else-path by having another if-clause with negated conditions. This gives you the possibility to override it with a second condition.
No, that is not possible (inside the same process).
Maybe you've misunderstood your problem.
If you want a code block to execute regardless of the condition, take it out of the if...else statement.
void foofunc(int n)
{
a = 44*n;
if(a == 484)
{
//do something
}
else
{
//do something if a DOES NOT equal 484
}
//do something regardless of the outcome of the test.
}
In this example, ridiculous though it is, the last line is outside the condition statement, so will execute whether a == 484 or not, which seems to me to be the same as making c trigger your else block regardless of the if test succeeds.
Of course, else blocks are not mandatory, so if you don't care what happens if your condition fails, then simply don't have an else block.
void foofunc(int n)
{
a = 44*n;
if(a == 484)
{
//do something
}
//do something regardless of the outcome of the test.
}
I assume you're trying to have both branches of this sort of statement execute?
Dim X As Boolean
X = False
If X = True Then
...
Else
...
End If
You could get it to execute using GoTo ... but that goes against good programming practice.
Dim X As Boolean
X = False
If X = True Then
...
Goto ElseStuff
Else
ElseStuff:
...
End If
Instead of that you should write separate procedures / functions to accomplish the behavior you'd like to have execute in both statements ... or simply put the code which should execute in all cases outside of the If block.
That would be functionally equivalent to using the GoTo, plus it makes it clear to anybody else.

Resources