user100046
user100046

Reputation: 452

Reuse variable in macro with modification

I'm trying to make a linked list for error handling in C. Functions would return the head element of the error list, or NULL.

I need macros to add file name, line numbers, ...

#define MAKE_ERR(MSG) \
  _err_malloc(__FILE__, __LINE__, __PRETTY_FUNCTION__, MSG, NULL)

#define PUSH_ERR(NEXT, MSG) \
  _err_malloc(__FILE__, __LINE__, __PRETTY_FUNCTION__, MSG, NEXT)

and I would like to make it easy to add the current frame as messages go up the stack:

#define FORWARD_ERR(NEXT) \
  (NEXT ? PUSH_ERR(NEXT, NULL) : NULL)


err_t* foo();

err_t* bar() {
  return FORWARD_ERR(foo());
}

The problem is that FORWARD_ERR uses NEXT twice.

I would like to use FORWARD_ERR as an expression. I can easily make it a block:

#define FORWARD_ERR(NEXT) \
  { err_t* N = (NEXT); return (N ? PUSH_ERR(N, NULL) : NULL) }

but I don't think that's a good solution.

I was trying to get it working with the Elvis operator a ?: b, but couldn't get it to work.

Upvotes: 2

Views: 237

Answers (1)

Carl Norum
Carl Norum

Reputation: 224982

Clang and GCC both support statement expressions, which would let you do something like this:

#define FORWARD_ERR(NEXT) \
  ({ err_t* N = (NEXT); N ? PUSH_ERR(N, NULL) : NULL; })

Which lets you use it as an expression the way you want to but doesn't force you to embed the return statement inside your macro.

Upvotes: 3

Related Questions