Search code examples
cmacrosc99variadic-macros

C99 Macro Expansion for Struct Member Access


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.


Solution

  • 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.