Подтвердить что ты не робот

Зачем возвращать отрицательную ошибку? (например, return -EIO)

Еще один простой пример:

if (wpa_s->mlme.ssid_len == 0)
    return -EINVAL;

Почему унарный минус? Является ли это (обычно) для функций, возвращающих > 0 при успешном завершении, и < (=) 0 при сбое или есть какая-то другая причина?

4b9b3361

Ответ 1

Это в основном причины. Множество функций имеет множество "хороших" положительных результатов, поэтому оставляет отрицательные значения для кодов ошибок.

Коды ошибок C/POSIX немного "исторически выросли", поэтому нет смысла пытаться приписывать им слишком много рифмы или разума.

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

Ответ 2

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

В мои старые дни Unix было что-то вроде соглашения, что 0 означало успех, положительное число означало небольшие проблемы, а отрицательное число означало какой-то провал. Поэтому было также своеобразное соглашение if (foo() >= 0) { /* success of a sort */ }.

Это, несомненно, связано с кодами возврата процесса Unix, где 0 был успешным.

Ответ 3

Ваше понимание в целом правильное. Очевидная интерпретация является правильной.

Стандартное соглашение несколько отличается от вашей формулы.

В Unix программа, которая завершает работу с проверками состояния 0 как истинное или успешное использование утилит уровня CLI, таких как оболочка. В библиотеке -1 обычно является возвратом ошибки.

Это приводит к общей парадигме, где >= 0 означает good, а < 0 означает ошибку. Ничто из этого не установлено в камне.

Кстати, это может быть классифицировано как шаблон часового пояса, и вы можете назвать его возвратом дозорного. На самом деле это комбинация "значения" и "код ошибки", и проще набирать и легче создавать потокобезопасность, чем возвращать код ошибки в одном месте и значение дозорного значения для ошибки в другой.

Википедия сообщает, что для прекращения цикла используется sentinel value, но я думаю, что функция return будет гораздо более распространенным экземпляром. Никто не отвечает за эти определения.

Ответ 4

С точки зрения оптимизации использование отрицательных чисел позволяет ядрам на основе Unix проверять код ошибки, используя только одно сравнение вместо двух.

Функции в ядре часто возвращают коды ошибок вместо указателей. Это означает, что коды ошибок не могут пересекаться с действительными адресами указателей, поэтому они должны быть либо самыми низкими значениями без знака (>= 0), либо самыми высокими (<= unsigned max).

Проверка значений указателя для NULL и для кодов ошибок - чрезвычайно распространенные операции, поэтому имеет смысл оптимизировать их.

Обычно нижние значения < 0x8000 равны NULL, а верхние значения - коды ошибок (помните, что -1 сохраняется как 0xff...ff, максимально возможное значение без знака).

Это означает, что вы можете использовать одно сравнение для проверки для каждого:

NULL, если x <= 0x8000 (true для 0 до 0x8000)

ERRNO, если x >= (unsigned long)(-MAX_ERRNO) (true для -1 в -MAX_ERRNO)

Это можно увидеть в файле err.h Linux.