Если у меня есть функция, которая возвращает какой-то указатель, я проверяю ошибки, устанавливая возвращаемое значение NULL в случае ошибки.
char *foo(void) {
//If stuff doesn't go okay
return NULL;
}
char *bar = foo();
if(!bar) return 1;
Это прекрасно работает, потому что я знаю, что в таких случаях я никогда не собираюсь возвращать NULL.
Однако иногда у меня будут функции, которые возвращают целые числа (в этом случае я читаю целые из файла конфигурации). Однако проблема заключается в том, что теперь нет способа проверить возвращаемое значение на наличие ошибок, поскольку любое значение (включая 0) может быть подлинным.
Пара обходных путей:
- Включить параметр кода ошибки в функцию
- Возвращает код ошибки и включает указатель int в качестве параметра
Проблема с обоими из них заключается в том, что у меня есть набор функций, которые все делают одно и то же, но для разных типов, и я хочу поддерживать обычный интерфейс, чтобы их можно было использовать одинаково.
Есть ли другое решение, которое не предполагает смену интерфейса на функцию? Какой самый распространенный способ справиться с этой ситуацией?
ВЫБРАННОЕ РЕШЕНИЕ
Спасибо за все ваши мысли и ответы на этот вопрос.
В конце я решил, что если функция предназначена для возврата некоторых данных, ошибку можно вернуть только через параметр ошибки. В противном случае ошибка возвращается напрямую.
Я выбрал этот корень, потому что, как правило, я обнаружил, что при возврате более сложных форм данных число потенциальных ошибок почти всегда превышало 1. Это означало, что использование NULL в качестве единственного источника данных об ошибках в любом случае нецелесообразно, поскольку это означало не было никакого способа определить, в чем на самом деле была ошибка. С помощью функций, возвращающих данные в виде целого числа, также стало невозможно отличить несколько разных кодов ошибок от достоверных данных.
Конечно, это не так для функций, которые на самом деле не возвращают никаких данных, и в этом случае я могу использовать возвращаемое значение в качестве кода ошибки.
Мне также нравится тот факт, что в приведенном выше шаблоне проводится четкое различие между функциями, которые возвращают данные, и функциями, которые этого не делают.