Поскольку ваш макрос зависит от типа возвращаемого значения, вы можете оценить выражение возврата и сохранить его в переменной правильного типа внутри первого уровня макроса, а затем использовать эту переменную. то есть:
#define CPFS_RETURN_BOOL(retval) do { \
bool _tmp_ = retval;
_CPFS_RETURN(_tmp_, _tmp_); \
} while (false);
Если я хорошо понимаю, этого должно быть достаточно для вашего варианта использования, а для других вариантов использования вы можете использовать функции.
В вашем примере вы получите:
do {
bool _tmp_ = inode && file_truncate(inode, len);
do {
util_cpfs_exit(_tmp_);
return _tmp_;
} while (0);
} while (0);
выглядит хорошо.
PS: в качестве идентификатора, если вы всегда используете _CPFS_RETURN косвенно через другой макрос, следуя приведенной выше модели, нет необходимости защищать его с помощью do { } while (false);
. Кроме того, размещение точки с запятой после while(false)
устраняет большую часть интереса к его использованию ... это может быть хорошим примером того, почему макросы C опасны и скрывают легкие ловушки. Не то, чтобы я не любил макросы, скорее наоборот. Я из (вероятно, редкого) вида людей, которые предпочли бы, чтобы макросы C были улучшены, чтобы обойти их текущие ограничения, чтобы стать действительно крутыми (и нет, шаблоны C ++ не являются улучшенными макросами, они являются чем-то совершенно другим).