Должен ли я вернуть значения TRUE / FALSE из функции C? - PullRequest
12 голосов
/ 18 февраля 2009

После программирования на C в течение нескольких лет я понял, что игнорирую соглашение C о возвращении нуля из функции, указывающей на успех. Соглашение кажется мне семантически неправильным, поскольку ноль, конечно, ложен. Проблема в том, что мне нравится называть функции, например, is_valid_foobar(), и чтобы соответствовать условию «ложные средства успеха», мне нужно быть более расплывчатым ... то есть вместо:

if ( ! is_valid_foobar() ) {
    return (error);
}

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

if ( validate_foobar() ) {
     return (error);
}

И моя реализация выглядит так:

int is_valid_foobar (int foobar ) {
     if ( foobar < MAX_ALLOWED ) {
          return TRUE;
      }
      return FALSE;
}

На самом деле я не замечал этого в обзорах кода. Так что я думаю, что это не такая уж ужасная привычка, но она «нетрадиционная». Мне любопытно, что думают люди.

Я очень осторожен с выбором, который я делаю для имен функций и переменных, и типичным комментарием к обзору является "код действительно ясен", и, кроме того, меня совсем не беспокоит необходимость набирать дополнительный 1013 * в начале вызова функции. Но что ты говоришь, о могущественные из С.О?

Ответы [ 11 ]

19 голосов
/ 18 февраля 2009

Я бы сказал, что оба они верны, для разных целей:

Если вы выполняете простую проверку go / no-go, например, is_numeric (), тогда true и false работают хорошо.

Для чего-то более сложного, парадигма успеха 0 == полезна тем, что позволяет возвращать более одного условия ошибки.

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

11 голосов
/ 18 февраля 2009

Соглашение не совсем то, что вы, кажется, думаете. Процессы должны выходить с состоянием 0, чтобы обозначить успех, а функции , которые возвращают коды ошибок , часто будут использовать 0, чтобы указать «нет ошибок». Но в качестве логического значения 0 должно означать ложь, а ненулевое значение должно означать истину. Если использовать 0 для логического true, вы когда-нибудь попадете на The Daily WTF.

6 голосов
/ 18 февраля 2009

Прошло много времени с тех пор, как я запрограммировал C, но я думаю, что вы говорите о двух разных видах функций здесь:

  • is_foo - это функция, которая проверяет некоторое свойство foo и возвращает 0 (false) или не- 0 (true), чтобы указать логическое значение этого свойства. При вызове этих функций состояние ошибки не ожидается (и если это происходит, оно отображается на одно из этих значений).
  • foo - это функция, которая выполняет действие foo. В случае успеха возвращается 0, а при ошибке - не 0.
3 голосов
/ 18 февраля 2009

C не имеет понятия логического значения, кроме 0 как ложного, а все остальное - true.

Идея возврата 0 исходит из наличия кода возврата, указывающего, что это за ошибка. Если вы не делаете код возврата, то нет ничего плохого в том, чтобы рассматривать 1 и 0 как true и false. В конце концов, TRUE и FALSE - просто typedef для 1 и 0 в C.

Это должно быть хорошо задокументировано, и ваши комментарии к функциям должны сказать explicity "Возвращает TRUE или FALSE".

Вы также могли бы написать if (is_invalid_foobar ()), который мог бы сделать заявление легким для понимания и все же семантически правильным.

3 голосов
/ 18 февраля 2009

Особенно, когда вы называете свою функцию is_foo (), стандартные символьные функции C (isdigit (), isupper () и т. Д.) Являются хорошим прецедентом для того, чтобы делать это по-своему.

3 голосов
/ 18 февраля 2009

Я не уверен, что согласен с тем, что существует соглашение о "возвращении нуля из функции, указывающей на успех".

AFAIK, соглашение состоит в том, что ноль равен false, и все ненулевые значения являются истинными в случае предикатов.

Однако это соглашение должно применяться только к очевидным предикатам, которые возвращают логические значения (например, true / false). Если основной целью функции является не возвращение логического значения (например, printf, fopen и т. Д.), То возвращаемое значение используется для указания причин сбоя, а затем вы можете принять соглашение UNIX «молчание или 0, если только есть проблема ".

Что касается возвращаемых значений, нет ничего плохого в использовании фиксированных возвращаемых значений, это делает все более удобным.

Большой риск, IMHO, заключается в том, что многие люди объявляют свои собственные константы, и когда другие используют одни и те же файлы, вы начинаете сталкиваться с конфликтами с их собственными константами. Таким образом, ваше ИСТИНА / ЛОЖЬ и конфликт с чужим ИСТИНА / ЛОЖЬ по линии.

2 голосов
/ 18 февраля 2009

Это не столько конвенция C, сколько оболочка UN * X. Рассмотрим стандартные функции C iasalpha (), isdigit () и т. Д. Все они возвращают ненулевое значение, чтобы указать успех. Итог: в C 'true' не равен нулю.

0 голосов
/ 17 октября 2012

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

0 голосов
/ 20 ноября 2009

Возвращаемое значение с помощью функции - условные обозначения для Истина и Ложь ИЛИ Успех и ошибка:

  1. API и т. Д. Показывают успех с возвращаемым значением 0 и отказ с возвращаемым значением = ненулевое значение ошибки.
  2. Если что-то верно; возврат функций 1. Например, isStackEmpty () вернет 1, если стек пуст.
0 голосов
/ 20 февраля 2009

для меня проверка на 0 кажется более естественной, и компилятор все равно оптимизирует ее, поэтому мне нравится писать, например,

if (check_foo == 0) // делаем что-то

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...