I have the following method in C to load a binary file, it seems rather long and tedious having to check the error value from each and every fread call, is there a neater way to handle this?
I'm aware that some of the calls could be reduced by reading in a struct in one go, but due to how C can add padding bytes in between struct members, I'd prefer to avoid this.
some_type_t *load_something(FILE *file) {
some_type_t *something = (some_type_t *)malloc(sizeof(some_type_t));
if (something == NULL) {
return NULL;
}
if (fread(&something->field1, sizeof(something->field1), 1, file) == 0) {
free(something);
return NULL;
}
if (fread(&something->field2, sizeof(something->field2), 1, file) == 0) {
free(something);
return NULL;
}
if (fread(&something->field3, sizeof(something->field3), 1, file) == 0) {
free(something);
return NULL;
}
uint16_t some_var1, some_var2, some_var3;
some_other_type_t *something_else1 = (some_other_type_t *)malloc(sizeof(some_other_type_t));
if (fread(&some_var1, sizeof(some_var1), 1, file) == 0) {
free(something);
free(something_else1);
return NULL;
}
some_other_type_t *something_else2 = (some_other_type_t *)malloc(sizeof(some_other_type_t));
if (fread(&some_var2, sizeof(some_var2), 1, file) == 0) {
free(something);
free(something_else1);
free(something_else2);
return NULL;
}
some_other_type_t *something_else3 = (some_other_type_t *)malloc(sizeof(some_other_type_t));
if (fread(&some_var3, sizeof(some_var3), 1, file) == 0) {
free(something);
free(something_else1);
free(something_else2);
free(something_else3);
return NULL;
}
// Do something with the vars and allocated something elses.
// ...
return something;
}
Why not creating a macro:
#define READ_FIELD(data) \
do { if (fread(&data, sizeof(data), 1, file) == 0) { \
free(something); \
free(something_else1);
free(something_else2);
return NULL; \
} } while(0)
then call it like a function call:
READ_FIELD(something->field1);
READ_FIELD(something->field2);
READ_FIELD(some_var1);
READ_FIELD(some_var2);
the code will be the same but at least it is now generated and not copied/pasted (with possible errors).
The macro has to call free on all possible memory blocks, even the ones that aren't allocated yet. The only constraint is to set the unallocated ones to NULL so free doesn't crash. And to be super safe change as:
free(something); something = NULL;
(of course if something is the copy of an allocated pointer, setting to NULL doesn't protect against double free, it has limits)
you can apply this technique to the write side as well, and since M Oehm suggested that, you could make a list of what you want to read/write in a wrapper macro:
#define DO_ALL \
DO_FIELD(something->field1); \
DO_FIELD(something->field2); \
DO_FIELD(some_var1); \
DO_FIELD(some_var2)
then define DO_FIELD as READ_FIELD or WRITE_FIELD:
#define DO_FIELD READ_FIELD
DO_ALL;
#undef DO_FIELD
There's nothing that could save you to check the success of each and every call, but you can improve on the code structure using goto (this is in fact one idiomatic use of goto in C, pseudo-code to follow):
if (first_call() < 0) goto error;
if (second_call() < 0) goto error;
// [...]
// when everything succeeded:
return result;
error:
// free resources
// return error-indicator, e.g.
return 0;
If the resources to free accumulate over the course of your function, make sure to first initialize them all to NULL/0 (assuming they are pointers). Then, calling free() on them in your error part has no effect when they're not allocated yet. If you use own "destructor functions", make sure to design them the same way free() is designed -- when passed a NULL value, it should be a no-op.
You need to initialize all something pointers to NULL and centralise the cleaning up at one place.
...
something = something_else1 = something_else2 = something_else3 = NULL;
...
some_other_type_t *something_else3 = (some_other_type_t *)malloc(sizeof(some_other_type_t));
if (fread(&some_var3, sizeof(some_var3), 1, file) == 0) {
goto error;
}
// Do something with the vars and allocated something elses.
// ...
return something;
error:
free(something);
free(something_else1);
free(something_else2);
free(something_else3);
return NULL;
}
Freeing a NULL pointer is OK, it does nothing, therefore you don't need to check if the someting pointers are NULL before calling free.
Sidenote: in C you don't cast the return value of malloc.
Here is a simple way to group the malloc and fread operations and check just once for proper completion:
some_type_t *load_something(FILE *file) {
uint16_t some_var1, some_var2, some_var3;
some_type_t *something = malloc(sizeof(*something));
some_other_type_t *something_else1 = malloc(sizeof(*something_else1));
some_other_type_t *something_else2 = malloc(sizeof(*something_else2));
some_other_type_t *something_else3 = malloc(sizeof(*something_else3));
if (!something || !something_else1 || !something_else2 || !something_else3 ||
!fread(&something->field1, sizeof(something->field1), 1, file) ||
!fread(&something->field2, sizeof(something->field2), 1, file) ||
!fread(&something->field3, sizeof(something->field3), 1, file) ||
!fread(&some_var1, sizeof(some_var1), 1, file) ||
!fread(&some_var2, sizeof(some_var2), 1, file) ||
!fread(&some_var3, sizeof(some_var3), 1, file))
{
free(something);
free(something_else1);
free(something_else2);
free(something_else3);
return NULL;
}
// Do something with the vars and allocated something elses.
// ...
return something;
}
Note that passing a null pointer to free() is OK.
Related
I have a function who's body looks a lot like this:
if (contains(array, element1) > -1){
// do something
} else if (contains(array, element2) > -1) {
// do something
} else if (contains(array, element3) > -1) {
// do someting
}...
The function contains will loop through my array and check to see if it contains an element that I pass to it and return either its position if it exists, or -1 if it doesn't.
In my // do something portion, I need the position of this element in the array. There are a couple of different ways I can do this:
I can call my contains() function once more to get the position.
I can define several variables that are defined as the return of the contain function, and then check them in my if-else block. So something like:
int element1Loc = contains(array, element1);
int element2Loc = contains(array, element2);
int element3Loc = contains(array, element3);
if (element1Loc > -1){
// do something
} else if (element2Loc > -1) {
// do something
} else if (element3Loc > -1) {
// do someting
}...
I can perhaps modify contain to return an int array[2], with array[0] equal to 0 or 1 whether the element is in it or not, and then array[1] qwould equal the actual location, making the code look like thiss:
if (contains(array, element1)[0] > -1){
// do something
} else if (contains(array, element2)[0] > -1) {
// do something
} else if (contains(array, element3)[0] > -1) {
// do something
}...
I can say screw the if-else block, save the return of contains in a variable and run several if-statements.
Solution one will search through my array at least twice. Solution two will search at least as many times as there are elements I'm looking for. Solution 3 is perhaps the best, but maybe not the most elegant. Solution 4 will run each if statement...
What is the best way to search just once? Should I make a function that takes all the things I am looking for and returns an array with the position of each element? Am I overthinking it?
I would modify contains to only use the return value to indicate the error/success of the find, and, if the parameter was found, output the parameter by reference.
int contains(int *data, int value, int *loc)
{
for(int i = 0; i < SIZE; i++)
{
if(data[i]==value)
{
*loc = i;
return 1; // success
}
}
*loc = -1;
return 0; // failure
}
Now, you can just do:
int elem1loc, elem2loc, elem3loc;
if(contains(data, val1, &elem1loc))
// use elem1loc...
if(contains(data, val2, &elem2loc))
// use elem2loc...
You could pass a pointer to say int which would be populated when the contains function finds an element. Then inside your if block you would be assured that pos is the correct index.
Example:
int pos;
if (contains(array, element1, &pos) > -1) {
// Here you can check pos for the position
} else if (contains(array, element2, &pos) > -1) {
// Here you can check pos as well...
}
Here's a solution that doesn't require you to modify contains at all:
int pos;
if ((pos = contains(array, element1)) > -1) {
// do something with pos
} else if ((pos = contains(array, element2)) > -1) {
// do something with pos
} else if ((pos = contains(array, element3)) > -1) {
// do something with pos
}
This works because variable assignment in most imperative languages is an expression.
I have a function which does some initialization and calls other functions, each of which returns an error code. I want to be able to return from this function after the first detected error like this:
int error_code = FirstFunction();
if (error_code != 0) {
return error_code;
}
error_code = SecondFunction();
if (error_code != 0) {
return error_code;
}
// etc...
However, not only does this look rather cumbersome, it also has multiple return statements, and for compliance reasons at my company this is not allowed.
How can I rearrange this so that there is only one return statement, but still stop after the first error code? The only way I can think of is to do nested if statements:
int error_code = FirstFunction();
if (error_code == 0) {
error_code = SecondFunction();
if (error_code == 0) {
error_code = ThirdFunction();
// etc...
}
}
return error_code;
But this could get unreasonable pretty fast. Is there another way to do this?
EDIT: In my program, return code of 0 means success (OK) and non-zero means failure/error (NOT OK)
You don't have to nest all the function calls, the code below do the job as well and should comply with your code writing rules:
error_code = FirstFunction();
if (error_code == 0) {
error_code = SecondFunction();
}
if (error_code == 0) {
error_code = ThirdFunction();
}
// etc...
return error_code;
Here is another lean method that can return different error codes depending on which function fails:
int func(void)
{
int code;
int error_code = (code = FirstFunction()) ? code :
(code = SecondFunction()) ? code :
(code = ThirdFunction()) ? code : 0;
/* ... */
return error_code;
}
Lean and clean (like this one, but avoiding the disliked gotos):
int foo(void)
{
int error_code;
do {
if (0 != (error_code = FirstFunction()))
{
break;
}
if (0 != (error_code = SecondFunction()))
{
break;
}
...
} while (0);
return error_code;
}
This, BTW, follows the more common pattern: 0 is OK, everything else isn't. Adjust as needed)
You could even obfuscate this using a macro:
#define RUN_AND_BREAK_ON_ERROR(rc, f, ...) \
if (0 != (rc = f(__VA_ARGS__))) \
{ \
break; \
}
int foo(void)
{
int error_code;
do {
RUN_AND_BREAK_ON_ERROR(error_code, FirstFunction, <args go here>);
RUN_AND_BREAK_ON_ERROR(error_code, SecondFunction, <args go here>);
...
} while (0);
return error_code;
}
if( (error_code = FirstFunction()) || (error_code = SecondFunction()) || ... ){
return error_code ;
}
return error_code; //denoting no error.
This would return only the first function which returns nonzero. The idea is that for if statement the first function that returns nonzero would short-circuit the whole evaluation and returns the error_code from the function which returned non-zero error_code. Also another thing is value of an assignment statement is the value assigned. That's why this works.
A more easier way would be to sequential if-else
if( error_code = FirstFunction() ) {}
else if( error_code = SecondFunction() ) {}
...
return error_code;
If all these functions take the same type of parameters and have the same return type, you could put them in a function array and iterate over it. When an error is found, it simply breaks out of the loop and returns.
int (*function_array[max_array])();
/*Fill the array with the functions you need*/
for(i=0;i<max_array;i++){
if((error_code=function_array[i]())!=OK){
break;
}
}
return error_code;
(OK is whatever the success return value is for these functions)
Well, there's the one used e.g. in the Linux kernel:
int somefunc(whatever)
{
if (do_something()) {
ret = -EINVAL;
goto err;
}
if (do_something_else()) {
ret = -EPERM;
goto err;
}
/* ... */
ret = 0;
err:
some_mandatory_cleanup();
return ret;
}
But I suspect that's going to be even less well received. (Before you scream, the whole point of that is the mandatory cleanup in the end. The goto arranges it to be executed always, but still puts it out of way.)
Really, I think the code in your first snippet is fine, and the issue is with your guidelines. Even if we only write return error_code; in one place, it's not enough to guarantee that the error code saved in variable is always correct, or that the function completes all cleanup that might be required. (Consider something that allocates memory, and has to release it in any case.)
so i am using jansson library and i want to set a value:
json_object_set_new(event, "error_code", json_integer(response->error_code));
The problem is that, i need to free response struct, but still use the value i have set in json_object_set_new.
Should i copy the value from response->error_code and how can i do that?
Some context:
plugin_response: {
if(!response->message && response->error_code == 0) {
response->error_code = JANUS_AUDIOBRIDGE_ERROR_UNKNOWN_ERROR;
if(response->error_cause == NULL) {
response->error_cause = g_strdup_printf("%s", "Invalid response");
}
}
json_t *event = json_object();
if(!response->message && response->error_code != 0) {
/* Prepare JSON error event */
json_object_set_new(event, "audiobridge", json_string("event"));
json_object_set_new(event, "error_code", json_integer(response->error_code));
json_object_set_new(event, "error", json_string(response->error_cause));
} else {
event = json_deep_copy(response->message);
}
if(root != NULL)
json_decref(root);
if(jsep != NULL)
json_decref(jsep);
g_free(transaction);
g_free(response);
return janus_plugin_result_new(JANUS_PLUGIN_OK, NULL, event);
}
EDIT: I am also using GLib, so if there is a nifty method for this, i am all ears.
Okey, i read this This article and i understood. I don't need to copy integer i am passing to json_integer(), because it's is not a pointer and is completely isolated from the structs integer.
I have ran into very strange behavior of my code, the basic flow of code is
main () parses a file and sets global variables accordingly.. such as
int frame_size, version;
typedef struct//file parsing variables
{
int frame,
int version; } configuration;
***//the function init_parse calls***
static int handler(void* user, const char* section, const char* name,
const char* value)
{
configuration* pconfig = (configuration*)user;
#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
if (MATCH("protocol", "version")) {
pconfig->version = atoi(value);
}
else if (MATCH("basic", "frames")) {
pconfig->frames= atoi(value);
frame_size=pconfig->frames;
}
else {
return 0; /* unknown section/name, error */
}
return 1;
}
main (){
configuration config;
if (ini_parse("test.ini", handler, &config) < 0) {
printf("Can't load 'test.ini'\n");
getchar();
iret = pthread_create(&hThread,NULL, pcapreader, NULL);
if(iret)
{
fprintf(stderr,"Error - pthread_create() return code: %d\n",iret);
exit(EXIT_FAILURE);
}
}
Now, the line followed by main()'s parsing line, everything seems set, but as soon as thread is started , the value frame_size changes to something 6345720:/
I have double checked code for possible replicated variable. thread only uses frame_size in for loop to check the limit.
the only problem was with initialization, once initialized, everything worked like a charm :)
I think it might never initialize the frame_size variable and never reached MATCH("basic", "frames") statement too.
Our code (in a simple library implementation) is beginning to look like this:
err = callToUnderlyingLibrary1();
if (err!=0) {
printf ("blah %d\n", err);
...
}
err = callToUnderlyingLibrary2();
if (err!=0) {
printf ("blah %d\n", err);
...
}
err = callToUnderlyingLibrary3();
if (err!=0) {
printf ("blah %d\n", err);
...
}
This is cumbersome and ugly. Is there a better way to do this ? Perhaps using the C preprocessor ? I was thinking something like:
CHECK callToUnderlyingLibrary1();
CHECK callToUnderlyingLibrary2();
CHECK callToUnderlyingLibrary3();
where the CHECK macro invokes the function and does the rudimentary error checking.
Are there preferred idiomatic ways of handling this ?
Another macro-based approach which you can use to mitigate the shortcomings in C fairly easily:
#define CHECK(x) do { \
int retval = (x); \
if (retval != 0) { \
fprintf(stderr, "Runtime error: %s returned %d at %s:%d", #x, retval, __FILE__, __LINE__); \
return /* or throw or whatever */; \
} \
} while (0)
Then to invoke it you have:
CHECK(doSomething1());
CHECK(doSomething2());
// etc.
For bonus points you could easily extend the CHECK macro to take a second argument y that is what to do on failure:
#define CHECK(x, y) do { \
int retval = (x); \
if (retval != 0) { \
fprintf(stderr, "Runtime error: %s returned %d at %s:%d", #x, retval, __FILE__, __LINE__); \
y; \
} \
} while (0)
// We're returning a different error code
CHECK(someFunction1(foo), return someErrorCode);
// We're actually calling it from C++ and can throw an exception
CHECK(someFunction2(foo), throw SomeException("someFunction2 failed")):
Usually, in C, one uses goto for error handling:
int foo()
{
if (Function1() == ERROR_CODE) goto error;
...
struct bar *x = acquire_structure;
...
if (Function2() == ERROR_CODE) goto error0;
...
release_structure(x);
return 0;
error0:
release_structure(x);
error:
return -1;
}
This can be improved with macros and more clever instruction flow (to avoid repeating cleanup code), but I hope you see the point.
I think you should look at exceptions and exception handling. http://www.cplusplus.com/doc/tutorial/exceptions/
try{
callToUnderlyingLibrary1();
callToUnderlyingLibrary2();
callToUnderlyingLibrary3();
}catch(exception& e)
//Handle exception
}
your library functions can throw exceptions if there is an error
Here is a proposition, you may or may not like it:
make your functions return 0 on failure, something else on success
if something fails in your functions, have them set a global (or static) variable to the error code (like errno)
create a die() function that prints the error depending of the error code (or whatever you want it to do)
call your functions with do_something(foo, bar) || die("Argh...");
I prefer a variant of Alexandra C.'s goto-approach:
int foo()
{
int rv = 0;
struct bar *x = NULL;
struct bar *y = NULL;
rv = Function1();
if (rv != OK){
goto error;
}
//...
x = acquire_structure();
if (x==NULL){
rv = ERROR_MEMORY;
goto error;
}
//...
rv = Function2();
if (rv != OK){
goto error;
}
//...
y = acquire_structure();
if (y==NULL){
rv = ERROR_MEMORY;
goto error;
}
//...
rv = release_structure(x);
x = NULL;
if (rv != OK){
goto error;
}
rv = release_structure(y);
y = NULL;
if (rv != OK){
goto error;
}
return OK;
error:
if (x!=NULL){
release_structure(x);
}
return rv;
}
When you use multiple goto-destinations, it is easy to mix them up. Or perhaps you move the initialization of a variable, but forget to update the gotos. And it can be very difficult to test all ways a C-method can fail.
I prefer having a single goto-destination that performs all the cleanup. I find that makes it easier to avoid mistakes.
You could do what you said, which is some rudimentary macro:
#define CHECK(x) (err = x()); \
if (err) { \
printf("blah %d on line %d of file %s\n", err, __LINE__, __FILE__); \
} \
else (void)0
And you could use it like
int err = 0;
CHECK(callToUnderlyingLibrary1); // don't forget the semicolon at the end
CHECK(callToUnderlyingLibrary2);
CHECK(callToUnderlyingLibrary3);
No 'goto', use only 1 'return' in functions. That's the elegant code.
IMHO, OP's question point and all answers are talking about FANCY techniques. Fancy code is just sort of eye candy.