Since your macro depends on the type of return value, you can evaluate the retval expression and store it in a variable of the correct type inside the first level of the macro, and then use this variable. i.e:
#define CPFS_RETURN_BOOL(retval) do { \ bool _tmp_ = retval; _CPFS_RETURN(_tmp_, _tmp_); \ } while (false);
If I understand well, this should be enough for your use case, and for other use cases you can use functions.
In your example, you will get:
do { bool _tmp_ = inode && file_truncate(inode, len); do { util_cpfs_exit(_tmp_); return _tmp_; } while (0); } while (0);
Looks nice.
PS: as a side element, if you always use _CPFS_RETURN indirectly through another macro, following the model above, there is no need to protect it with do { } while (false); . Also, adding a semicolon after while(false) eliminates much of the interest in using it ... this may be a good example of why C macros are dangerous and hide light traps. Not that I didn't like macros, quite the opposite. I am from (possibly rare) people who would prefer that C macros be expanded to circumvent their current limitations, to become really cool (and no, C ++ templates are not improved macros, they are completely different).
source share