Тип возвращаемого значения функции без знака, в то время как он возвращает -1 для ошибки

Я уже давно использую libnet и заметил, что есть некоторые функции, которые возвращают значение uint32_t который, насколько я понимаю, является неподписанным типом. Тем не менее, в документации говорится, что нужно вернуть -1, если произошла ошибка (тип со знаком). libnet_get_ipaddr4, libnet_get_prand, например.

Тем не менее, я использую такие функции без проблем:

if ((src_ip_addr = libnet_get_ipaddr4(l)) == -1) { /* treat the failure*/ }

Я предполагаю, что сравнение происходит между -1, интерпретируемым как unsigned int, с возвращаемым значением, которое принимает то же значение; Сравнение верно.

Хотя это, очевидно, работает, мой вопрос: имеет ли это смысл? Зачем? Как программист, как я должен проверить возвращаемое значение, чтобы узнать, произошла ли ошибка? Является ли приведенный выше фрагмент кода правильным?

1 ответ

Решение

Цитирование стандартного проекта C99, 6.2.5.9:

Вычисления с использованием беззнаковых операндов никогда не могут переполниться, поскольку результат, который не может быть представлен результирующим целочисленным типом без знака, уменьшается по модулю на число, которое на единицу больше, чем наибольшее значение, которое может быть представлено результирующим типом.

Так что -1 автоматически конвертируется в UINT32_MAX,

Предупреждение. Работа со значениями вне допустимого диапазона не так хороша для подписанных типов. Смотрите здесь и здесь для различных осложнений.

6.5.9 говорит, что для операторов равенства

Если оба операнда имеют арифметический тип, выполняются обычные арифметические преобразования.

6.3.1.8 описывает эти преобразования:

[...] В противном случае, если операнд с целым типом без знака имеет ранг, больший или равный рангу типа другого операнда, тогда операнд с целым типом со знаком преобразуется в тип операнда с целым типом без знака, [...]

(Вы можете использовать стандарт для аналогичного обоснования возврата -1 для функции, возвращающей подписанный тип, но это в основном тот же аргумент, поэтому я не буду беспокоиться.)

Другими словами, да, это совершенно правильно.

Другие вопросы по тегам