Reputation:
I have this C code :
#include<stdio.h>
typedef struct {
int foo;
} MyStruct;
MyStruct init_mystruct(void);
int main(void) {
MyStruct mystruct = init_mystruct();
if( mystruct == NULL ) {
/* error handler */
}
return(0);
}
MyStruct init_mystruct(void) {
MyStruct mystruct;
int is_ok = 1;
/*
* do something ...
*/
/* everything is OK */
if( is_ok )
return mystruct;
/* something went wrong */
else
return NULL;
}
It has a structure and a function to initialize that structure. What I'm trying to do is to return NULL if there was a failure in that function.
The gcc error message :
code.c: In function ‘main’:
code.c:13: error: invalid operands to binary == (have ‘MyStruct’ and ‘void *’)
code.c: In function ‘init_mystruct’:
code.c:34: error: incompatible types when returning type ‘void *’ but ‘MyStruct’ was expected
It looks that returning NULL instead of a structure is not valid, so how do I express the failure of structures initialization in this case (no structure pointer)?
Upvotes: 19
Views: 59153
Reputation: 500307
if( mystruct == NULL )
mystruct
is not a pointer, so you cannot compare it with NULL
.
You have three options:
MyStruct
to indicate whether the struct has been initialized correctly.Upvotes: 20
Reputation: 881323
A structure is not a pointer. If you want to be able to return NULL, you're going to have to allocate the structure on the heap so you can return a pointer to it, and let the caller clean up afterwards.
That way, you can indicate failure, something like:
MyStruct *init_mystruct (void) {
MyStruct *mystruct = malloc (sizeof (*mystruct));
if (mystruct != NULL)
return NULL;
int is_ok = 1;
/* do something ... */
/* everything is OK */
if( is_ok )
return mystruct;
/* something went wrong */
free (mystruct);
return NULL;
}
int main (void) {
MyStruct *mystruct = init_mystruct();
if (mystruct == NULL) {
/* error handler */
return -1;
}
free (mystruct);
return 0;
}
Upvotes: 9
Reputation: 26094
NULL
can be used if a function returns a pointer. In this case, you return an object, which means that you have to return a real, existing object.
One way of doing this is to have an "ok" field in the struct that you could set in the init function, and that you could check in the caller.
Another way is to rewrite your code so that you allocate a struct dynamically and return a pointer, that way you could return NULL on failure. (Note, however, that there are other drawbacks of allocating things dynamically.)
Upvotes: 2