Is it possible to do a nullity check and an access in a macro?
Eg:
#define LOG(mystruct, severity, format, ...) ({ \
severity_t current = ERROR; \
if (mystruct) { \
current = mystruct->error_level; \
} \
if (severity >= current) { \
... //handle logging
} \
})
If I call this with LOG(NULL, DEBUG, "test %s", "one");
I get an error as such:
error: member reference base type 'void' is not a structure or union note: expanded from macro 'LOG' current = mystruct->error_level;
mystruct is defined as:
typedef struct mystruct_t {
severity_t error_level;
}
I want to allow the possibility of working with a NULL mystruct
. Eg: case of when there is an error creating the structure itself.
Your problem is that although the first branch will never been taken, NULL
hasn't the correct type to do a ->error_level
.
You can avoid that by giving it the right type. I would do that with a local variable, not a cast so you'd capture wrong use cases of your macro. Just add
yourType* myStr = mystruct;
current = myStr->error_level;
and you should be fine.
Is it possible to do a nullity check and an access in a macro?
Nope, the preprocessor is doing simple text replacement. It doesn't support conditionals inside the definition of a macro.
When you use the macro with LOG(NULL, DEBUG, "test %s", "one");
, the fourth line expands to
current = NULL->error_level;
and since NULL
is typically defined as #define NULL ((void *)0)
, that further expands to
current = ((void *)0)->error_level;
which is why you get the message about void
not being a structure or union.
To fix the problem, don't pass NULL
to the macro, pass the pointer that contains NULL
to the macro, eg
mystruct_t *ptr = malloc(...);
if ( !ptr )
LOG( ptr, DEBUG, "no memory" );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.