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

Правильное использование exit() в С++?

Я написал простое приложение, которое читает файл данных, анализирует текст и затем обрабатывает некоторые данные. Файл данных открывается в моей функции main(). Является ли хорошей практикой программирования использование функции exit(), если определено, что файл не был открыт должным образом? например:

if (!file.is_open() ){
     exit(1);
}

Кроме того, моя программа имеет отдельную функцию для анализа данных в файле. Эта функция вызывается main(). Если функция обнаруживает ошибку в данных, я хочу, чтобы программа остановилась после печати сообщения об ошибке. В такой ситуации приемлемо ли использовать функцию exit() в моей функции синтаксического анализа? Я задаю этот вопрос, потому что для меня, похоже, не очень аккуратно разрешить функции выхода из программы самостоятельно, не возвращая управление функции main(). (Я прошу прощения, если этот вопрос кажется довольно очевидным. Я новичок в С++ и программировании вообще).

4b9b3361

Ответ 1

Вызов exit из функции не является "плохим" в том смысле, что он имеет четко определенное поведение - в этом нет ничего принципиально неправильного.

Но, если вы пишете функцию, которая может закончиться, например, в библиотеке, вызов exit из-за плохой практики в целом: гораздо лучше сообщить об ошибке вызывающему коду (через конкретную возвращаемое значение или исключение, например), и позвольте вызывающему коду решить, что делать. (Есть случаи, когда он отлично действует, хотя, например, если вы пишете функцию под названием quit_if_file_not_found, ну, ваши пользователи ожидают завершения.)

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

(И не просто exit, не печатая сообщение об ошибке или не записывая что-то вроде того, что вы делаете выше, это сделает для разочарованных пользователей, которые не могут знать, как исправить любую проблему, с которой столкнулся код.)

Ответ 2

Есть два аспекта. Одним из них является заинтересованность в принятии решения о прекращении программы в том месте, где вы хотите использовать exit, а другой - в использовании выхода. Мат ответ охватывает первый.

Во втором случае exit обычно является плохим выбором на С++. Причина в том, что он выполняет некоторую очистку (функции, зарегистрированные с помощью atexit и иногда включающие деструкторы некоторых объектов статической продолжительности хранения), но не все из них (деструкторы объектов в стеке), и по моему опыту вы либо хотите все из него или нет.

Ответ 3

exit(0) указывает на успешное завершение программы и полностью переносится, хотя

exit(1) (обычно) указывает на неудачное завершение. Однако использование не переносится.

Ответ 4

Из main нет разницы в exit(1) или return 1. Вы используете значение возврата/выхода 0 для успеха и не 0 для отказа.

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

В любом случае хорошей практикой является документирование того, что делает функция, будь то код exit, return или exception.

Ответ 5

Это зависит от того, откуда этот exit(1). Вы не должны называть это exit(1) из библиотеки, только из вашего собственного приложения.

Если вам нужно установить код ошибки, вы можете установить errno (переменная STD C, да).

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

Ответ 6

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