используйте макрос для проверки возвращаемого значения функции в C - PullRequest
0 голосов
/ 17 февраля 2020

Я хочу иметь макрос, который выполняет что-то вроде:

#define TEST(_ptr) ({ if ((_ptr) == NULL) ERROR; (_ptr); })

, который проверяет _ptr и вызывает ERROR макрос или возвращает его значение.

Однако, если я использую что-то вроде var = TEST(fun()), это приводит к тому, что fun() вызывается два раза.

Я могу сделать что-то вроде:

#define TEST(_tmp, _ptr) ({ _tmp = _ptr; if ((_tmp) == NULL) ERROR; (_tmp); })

is Есть ли чистый способ сделать это без передачи временного хранилища, например, используя оператор typeof!?

Ответы [ 3 ]

1 голос
/ 17 февраля 2020

Вместо того, чтобы использовать определение макроса, почему бы не использовать обычную функцию как в:

void *funcCaller (void *f) {
    if (f == NULL) {
        ERROR;    // not sure what the ERROR thing is supposed to do or look like.
    }

    return f;
}

Затем вызвать ее как в:

p = funcCaller (func());

Поскольку список аргументов для funcCaller() использует void *, тогда тип возвращаемого значения func() может быть указателем любого типа.

0 голосов
/ 17 февраля 2020

Вы можете сделать так:

/* Assuming your ERROR, something like this */
#define ERROR \
({ \
    printf("Error, Null pointer passed\n"); \
    exit(1); \
})

#define TEST1(_ptr) \
({ \
    typeof(_ptr) _tmp = _ptr; \
    if ((_tmp) == NULL) ERROR; \
    (_tmp); \
})
0 голосов
/ 17 февраля 2020

Сравнивая (_ptr) == NULL Я предполагаю, что ваш func() возвращает указатель. В этом случае вы можете изменить макрос TEST(_ptr) на:

#define TEST(_ptr) ({ void* _rt = _ptr; if ((_rt) == NULL) ERROR; (_rt); })
...