Error Handling Strategies in C?

Based on the code below:

typedef struct {int a;} test_t; arbitrary_t test_dosomething(test_t* test) { if (test == NULL) { //options: //1. print an error and let it crash //eg fprintf(stderr, "null ref at %s:%u", __FILE__, __LINE__); //2. stop the world //eg exit(1); //3. return (ie function does nothing) //4. attempt to re-init test } printf("%d", test->a); //do something w/ test } 

I want to get a compiler error if test ever NULL , but I assume this is not possible in C. Since I need to perform a null check at runtime, which option is the most suitable way to handle it?

+4
source share
8 answers

If you never want a function to be called with a null pointer (i.e., a non-null pointer is a prerequisite for calling the function), you can use the statement at the top of the function:

 assert(test != NULL); 

This can help you with debugging to find places in the code where you are calling a function with a null pointer.

+7
source

We really cannot categorically answer this question. It depends a lot on what the software will be used for. If it provides radiation, you want it to print an error and exit(1); . If you are writing a business application, you probably want to register a bug and just go back. All about the context.

+4
source

I would use the statement at the beginning of the function:

 arbitrary_t test_dosomething(test_t* test) { assert(test != NULL); printf("%d", test->a); //do something w/ test } 

You will not get a compiler error. But when developing (debugging) your program will stop and point you to this assert code in the code.

+1
source

Use setjmp .

http://en.wikipedia.org/wiki/Setjmp.h

http://aszt.inf.elte.hu/~gsd/halado_cpp/ch02s03.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; } 
+1
source

It really depends on your use case. If you have an interactive application, enter the query and the user will correct the entry. If this is a server process, you may want to register. If the error forces your program to go south, then complete the statement.

0
source

You cannot get a compiler error if the test is NULL, this is a runtime value, and this may even depend on user input, the compiler is not able to find out its value.

To avoid calling a function with a NULL value, use assert:

 assert(test != NULL); 

This means: my code cannot handle NULL as input. And it will be interrupted at runtime.

Your function is supposed to return an arbitrary_t and return nothing.

You can also send an error back to the caller in a return value that you are not currently using, for example, instead return an arbitrary_t * that will be NULL if it cannot be allocated (which would be if test_t was NUL). The caller must check for this.

0
source

Apparently (I recently searched the web for “C static assert”), C ++ 0x has static_assert, and C people are talking about something similar for the next C standard. Of course, this means there is currently no standard " static assert "in C.

Some people offer C preprocessor macros that define enums or structures that use a boolean expression, and the ?: Operator to generate an invalid enum / struct definition if the conditional expression fails. (A number of such macros are listed above the web search.)

Personally, since I always use gcc, I just declare functions like

 foo_t function(moo_t *moo) __attribute__(( nonnull(1) )); 

and therefore, the compiler gives me a warning ( -Wnonnull included in -Wall ) if I accidentally call a function with a parameter set to NULL .

0
source

I can only repeat this - it depends on your application.

A good rule is to detect the error as early as possible. This usually makes it easier, faster, and cheaper to find and fix the problem. Ideally, you would catch this during development. As you noticed, you cannot catch it at compile time (unless you switch to the language of “design by contract” such as Eiffel), so you catch it at run time.

And then ... it depends ...

If this is a desktop application, then perhaps a huge dialog box and exit is the fastest way to fix it if it makes someone report an error. If possible, you might have the idea of ​​sending an email to the developer (for example, if this is your own application).

If this is critical or vital, you just need to restart the application (this is a common approach in embedded systems).

No matter what you decide, try to collect as much information as possible about the problem. For example, you can flip your won macro to wrap around ASSERT, which adds FILE and LINE ).

I am using the following:

 #ifdef TESTING #define ASSERT_MSG(subsystem, message, condition) if (!(condition)) {printf("Assert failed: \"%s\" at line %d in file \"%s\"\n", message, __LINE__, __FILE__); fflush(stdout); abort();} /* we can also use this, which prints of the failed condition as its message */ #define ASSERT_CONDITION(subsystem, condition) if (!(condition)) {printf("Assert failed: \%s\" at line %d in file \%s\"\n", #condition, __LINE__, __FILE__); fflush(stdout); abort();} #else #define ASSERT_MSG(subsystem, message, condition) if (!condition) DebugTrace(FATAL, subsystem, __FILE__, __LINE__, "%s", message); #define ASSERT_CONDITION(subsystem, condition) if (!(condition)) DebugTrace(FATAL, subsystem, __FILE__, __LINE__, "%s", #condition); #endif 
0
source

Source: https://habr.com/ru/post/1308629/


All Articles