Reputation: 452
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
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