Каковы общие подходы к значениям возвращаемых значений функций? - PullRequest
6 голосов
/ 04 декабря 2009

Я знаю, EXIT_SUCCESS / EXIT_FAILURE обычно используется для выхода из main (), чтобы указать успешность программы.

Но используется ли он (обычно или предлагается) для нормального возврата функций? Я пытаюсь написать какой-то "стандартный" код, поэтому мне интересно, стоит ли использовать их вместо 0 или -1 ..

Ответы [ 7 ]

13 голосов
/ 04 декабря 2009

Не используйте EXIT_SUCCESS или EXIT_FAILURE для функций или для чего-либо, кроме exit вызовов по этому вопросу.

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

Некоторые общие подходы:

  • Функции, возвращающие указатели, почти всегда возвращают NULL (что соответствует 0 в соответствии с ANSI C, но NULL - более описательное имя для использования) в случае ошибок
  • Функции, которые возвращают индексы или позиции, обычно возвращают -1 при ошибке (потому что это не может быть реальный индекс, а 0 может, так что 0 не является хорошим возвращаемым значением ошибки)
  • В более сложных случаях может оказаться полезным определить новый тип возвращаемого значения с помощью enum, одним из которых является ваша ошибка, и проверить это.

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

4 голосов
/ 04 декабря 2009

Никогда не следует использовать EXIT_SUCCESS или EXIT_FAILURE вне контекста вызова exit() или возвращаемого значения main(). Значения этих целых чисел не определены стандартом, поэтому вы не можете написать переносимый код, если предположите, что они равны 0 или 1 соответственно.

Стандарт определяет, что exit(0) и return 0 из main() ведут себя так же, как exit(EXIT_SUCCESS) и return EXIT_SUCCESS, но эти значения являются "особыми" в том смысле, что они должны интерпретироваться в реализации определенным образом. То есть фактическое значение, передаваемое в систему, может не быть 0, а постоянное значение EXIT_SUCCESS может быть не равным 0, если этого требует реализация, при условии, что return 0 из основного и return EXIT_SUCCESS из основного ведут себя так же.

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

int MyFunction1 () { /* ... */ return EXIT_SUCCESS; }
int MyFunction2 () { /* ... */ return 0; }

// Portable:
if (MyFunction1 () == EXIT_SUCCESS) { ... }
if (MyFunction2 () == 0) { ... }
if (!MyFunction2 ()) { ... }

// Not portable:
if (MyFunction1 () == 0) { ... }
if (!MyFunction1 ()) { ... }
if (MyFunction2 () == EXIT_SUCCESS) { ... }

Проблема становится более очевидной с EXIT_FAILURE:

int MyFunction1 () { /*... */ return EXIT_FAILURE; }
// Not portable
if (MyFunction1 ()) { ... }
if (MyFunction1 () == 1) { ... }
// The only way to make this portable.
if (MyFunction1 () == EXIT_FAILURE) { ... }
3 голосов
/ 04 декабря 2009

Многие из функций, определенных стандартом POSIX, возвращают 0 в случае успеха или ненулевой код ошибки, указывающий на ошибку.

Определено множество функций POSIX, которые возвращают 0 в случае успеха, -1 в случае сбоя и задают глобальную переменную errno, чтобы указать, что не удалось. Но глобальная errno не работает хорошо в многопоточной программе.

1 голос
/ 04 декабря 2009

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

0 голосов
/ 04 декабря 2009

EXIT_SUCCESS - символическая константа .-

Вы можете использовать EXIT_SUCCESS и EXIT_FAILURE, а также 0 для ОК и не 0 для сбоя.

Зависит от вкуса, вы также можете сделать это

#define WRONG 1
#define COOL  0

и верните их .-

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

Надеюсь, это поможет!

0 голосов
/ 04 декабря 2009

Я не использую макросы EXIT_ * для функций, потому что:

  • Некоторые из моих функций должны возвращать подписанную ошибку при ошибке
  • Некоторые из моих функций должны возвращать количество прочитанных или записанных байтов
  • Я предпочитаю обрабатывать ошибки с помощью типизированного указателя на функцию обратного вызова
  • Мне нравится оставаться последовательным

Теперь мы подошли к main ():

  • POSIX Говорит, что вы можете выйти со значением 0 - 255. Очень и очень полезно возвращать значимый статус выхода, а не просто успех или неудачу. Это помогает сделать сценарии более интеллектуальными. В этом отношении полезен только EXIT_SUCCESS.
0 голосов
/ 04 декабря 2009

Я бы сказал, что это не имеет значения.

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