Можно ли создать макрос, который расширяет следующий код
int error = 0;
struct parse_tree res = CLEANUP_parse(file_hdl);
// ...
cleanup:
return error
в нечто семантически эквивалентное (достаточное) для
int error = 0;
struct parse_tree res;
struct parse_tree tmp = parse(file_hdl);
if(global_error_variable != 0) {
error = global_error_variable;
goto cleanup;
} else {
res = tmp;
}
// ...
cleanup:
return error
Причина, по которой я боюсь, что это невозможно, в том, что goto label;
- это утверждение, и мне действительно нужно выражение. Например. что-то вроде
#define CLEANUP_parse(file_hdl) ((tmp=parse(file_hdl)) ^ tmp ^ global_error_variable) ? goto cleanup : tmp
не работает по этой причине (и потому что tmp
не объявлено и, возможно, больше).
К сожалению, расширения компилятора возможны только в том случае, если GCC, VSC и компилятор Texas Instrument C их поддерживает.
Фон
У нас есть существующая кодовая база, где каждая функция возвращает целочисленный код ошибки, и вызывающая сторона переходит к cleanup:
при ненулевом коде возврата. Я рассматриваю введение функций, которые используют глобальный код ошибки, чтобы разрешить использование их возвращаемого значения, но хотят сделать это безопасным и обратно совместимым способом. Полная картина на SE Code Review