Могу ли я создать макрос, который условно `goto`s и служит выражением? - PullRequest
2 голосов
/ 18 апреля 2019

Можно ли создать макрос, который расширяет следующий код

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

...