I was looking for a macro that will resemble the with-construct. The usage should be something like:
with (lock(&x), unlock(&x)) {
...
}
It might be useful for some other purposes.
I came up with this macro:
#define __with(_onenter, _onexit, v) \
for (int __with_uniq##v=1; __with_uniq##v > 0; )\
for (_onenter; __with_uniq##v > 0; _onexit) \
while (__with_uniq##v-- > 0)
#define _with(x, y, z) __with(x, y, z)
#define with(_onenter, _onexit) _with(_onenter, _onexit, __COUNTER__)
It has 3 nested loops because it should:
- Initialize loop counter (C99 only, of course)
- Possibly initialize variable _onenter (such as
with (int fd=open(..), close(fd))
) - Allow
break
inside the code block. (continue
is allowed too. And the macro could be adjusted toassert()
it out)
I used it on the code for the XV6 OS and it seems quite useful.
My question is - what are the worst problems with such a macro? I mean, besides the mere usage of a C macro (especially one that implements new control-flow construct).
So far have found these drawbacks / problems:
- No support for
return
orgoto
(but it can save somegoto
s in kernel code) - No support for errors (such as
fd < 0
). I think this one is fixable. - gnu89 / c99 and above only (loop counter. the unique variable trick is not necessary)
- Somewhat less efficient than simple lock-unlock. I believe it to be insignificant.
Are there any other problems? Is there a better way to implement similar construct in C?