|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|
О корректном завершении программ на с++01.11.2025, 19:49. Показов 6564. Ответов 77
Метки нет (Все метки)
Доброго времени суток,
Изучая книгу Страуструппа "Язык программирования С++. Специальное издание", обратил внимание на следующее утверждение "При вызове exit() не будут вызваны деструкторы локальных переменных во всех функциях вверх по цепочке имевших место функциональных вызовов. Генерация и перехват исключений гарантируют корректное уничтожение локальных объектов. Вызов же exit() не позволяет корректно отработать всем функциям из цепочки вызовов. Поэтому лучше не ломать контекст вызова функций и просто сгенерировать исключение, а вопрос о том, что делать дальше, оставить обработчикам" Допустим, в моей программе в месте, далеком по цепочке вызовов от main(), возникло событие, означающее что программа штатно закончило свою работу. Означает ли написанное выше что: 1) не стоит использовать библиотечные фукнции std::exit(), std::abort() 2) можно не заморачиваться с "правильным" завершением всех функций из цепочки вызовов, а достаточно сгенерировать исключение throw finish(), например. Разместить обработчик в main() и предусмотреть в нем вызов деструкторов глобальных объектов? Хотелось бы понять и запомнить как правильно поступать при необходимости завершения сложных программ, от которых зависят в т.ч. другие процессы. Понятно, что простые учебные программы можно завершать как угодно.
0
|
|
| 01.11.2025, 19:49 | |
|
Ответы с готовыми решениями:
77
Корректное закрытие программы при завершении работы Windows Корректное завершение работы сокетов Корректное завершение потока |
|
фрилансер
6455 / 5656 / 1129
Регистрация: 11.10.2019
Сообщений: 15,062
|
||||
| 01.11.2025, 20:15 | ||||
![]()
2
|
||||
|
425 / 147 / 27
Регистрация: 12.12.2020
Сообщений: 1,192
|
|
| 01.11.2025, 20:19 | |
|
Можно не заморачиваться с вызовом деструкторов если речь идет только об освобождении выделенной памяти.
Другое дело если в деструкторах прописана какая то функциональная составляющая, например сохранить текущее состояние на диске, сохранить данные в базе данных, закрыть соединения и т.д. Операционка очистит всю память, разорвет все соединения, освободит все занятые файлы. Вопрос чисто в работе программы.
0
|
|
|
фрилансер
6455 / 5656 / 1129
Регистрация: 11.10.2019
Сообщений: 15,062
|
|
| 01.11.2025, 20:21 | |
|
0
|
|
|
425 / 147 / 27
Регистрация: 12.12.2020
Сообщений: 1,192
|
||
| 01.11.2025, 20:23 | ||
|
0
|
||
|
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
|
|||
| 01.11.2025, 20:26 | |||
|
Если программа закончила свою работу, то программа уже не работает, она уже завершилась. Событие "программа закончила свою работу" означает, что программы больше нет. Завершившаяся программа принципиально не может реагировать на событие собственного завершения. А кроме того, если факт завершения программы возник в месте, далеком по цепочке вызовов от main, тогда такое завершение - это аварийное завершение, а вовсе не штатное. Штатное завершение - это, по-другому, "корректное завершение". Для корректного завершения необходимо корректное завершение функции main. Для этого нужно сначала дождаться корректного завершения всех дочерних потоков, и потом корректно выйти из функции main. Обычно делают так: пускают сигнал о том, что нужно остановить всю работу. Поток функции main ждёт, когда все дочерние потоки завершатся, и потом тоже завершается. Кидать исключение для этого не нужно. Механизм исключений предназначен для того, что бы обрабатывать нештатные ситуации, а не для того, что бы обрабатывать штатные. Добавлено через 22 секунды
2
|
|||
|
фрилансер
6455 / 5656 / 1129
Регистрация: 11.10.2019
Сообщений: 15,062
|
|
| 01.11.2025, 20:37 | |
|
Alex1126, дальше не было смысла цитировать
0
|
|
|
6195 / 2896 / 1043
Регистрация: 01.06.2021
Сообщений: 10,635
|
||
| 01.11.2025, 20:56 | ||
|
Так что, все мы постоянно используем этот exit.
0
|
||
|
фрилансер
6455 / 5656 / 1129
Регистрация: 11.10.2019
Сообщений: 15,062
|
||
| 01.11.2025, 21:21 | ||
|
Royal_X, ну, также можно сказать, что мы постоянно используем goto, ведь он там в машинном коде повсеместно
0
|
||
|
6195 / 2896 / 1043
Регистрация: 01.06.2021
Сообщений: 10,635
|
|
| 01.11.2025, 21:24 | |
|
Алексей1153, я всегда и говорю, что использую goto)
0
|
|
|
фрилансер
6455 / 5656 / 1129
Регистрация: 11.10.2019
Сообщений: 15,062
|
|
| 01.11.2025, 21:32 | |
|
Royal_X,
0
|
|
|
6195 / 2896 / 1043
Регистрация: 01.06.2021
Сообщений: 10,635
|
|
| 01.11.2025, 21:36 | |
|
Алексей1153, чем тебе goto не нравится? Единственный нормальный инструмент для выхода из нескольких вложенных циклов. И это одобряется экспертами и даже Misra C++. Конечно, даже в этом случае вместо goto можно использовать функцию или прочие подходы, но все они отстой.
1
|
|
|
2642 / 1653 / 267
Регистрация: 19.02.2010
Сообщений: 4,377
|
||||
| 01.11.2025, 22:13 | ||||
|
У тебя С++, т.е. ООП с полиморфизмом. А также с условной компиляцией, возможной со времён С. И с возможностью передавать проге аргументы через командную строку. Это означает, что и локальные, и даже глобальные объекты могут создаваться разными для разных билдов (для отладочного и для релизного), и/или при разных аргументах командной строки. Например, в отладочном билде (или при некотором ключе, в зависимости от значения которого создаётся тот или иной наследник некоторого базового типа) объекты могут что-то логировать. И "убивание" проги - оставит лог кривым (файл-то лога ОСь закроет - но вот его содержание останется "оборванным", не отразившим возможный возврат вверх по дереву вызовов). Поэтому лучше штатно возвращаться вверх по цепочке вызовов. Ибо в сложных прогах (при коллективе разработчиков) - не ты можешь создавать/кодить какие-то лок.объекты / локальные вызовы, и не надо своим кодом рубить неизвестные тебе (или будущие потенциальные) возможности чужих объектов/частей проги. Ну или ты можешь видеть только интерфейс базового (абстрактного класса), а каких там потомков с той или иной функциональностью породят затем от него другие кодеры - тебе неизвестно. Т.е. лучше свою часть кода реализовывать так, чтобы не предполагать ничего о работе чужого кода.
1
|
||||
|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|||
| 01.11.2025, 23:26 [ТС] | |||
![]() Например, main() вызвало функцию модуля пользовательского интерфейса, оттуда был вызван управляющий модуль, который вызвал лексический анализатор, который получил данные от модуля работы с файлами и где-то, во глубине нескольких вложенных циклов нашел искомый результат ![]() ![]() Я пользуюсь goto внутри функций, когда искомый результат получен, и надо перейти куда-то ближе к заветному return "что-то там". А тут, прочитав Страуструппа, что можно завершить программу выбросив исключение, в котором можно и структуру с данными пробросить, я подумал, а может быть это оно... И goto не нужно... Прочитав Ваши ответы, я не увидел ни одного ответа ЗА завершение программы исключением, но увидел несколько ПРОТИВ. Не буду мусорить себе мозг этим "концептом".
0
|
|||
|
6195 / 2896 / 1043
Регистрация: 01.06.2021
Сообщений: 10,635
|
||
| 01.11.2025, 23:40 | ||
|
ADnD, лучше выложи свой код или хотя бы часть.
0
|
||
|
Неэпический
|
|||||
| 01.11.2025, 23:46 | |||||
Сообщение было отмечено Folian как решение
Решение![]() Исключения нужны для обработки ошибок, не нужно использовать их для костыльного управления выполнением. Хотя, если вы злой колдун... ![]() ![]()
2
|
|||||
|
фрилансер
6455 / 5656 / 1129
Регистрация: 11.10.2019
Сообщений: 15,062
|
|||
| 02.11.2025, 10:15 | |||
|
Он мне ни разу не пригодился, ну и я даже не знаю, где бы он мог пригодиться Добавлено через 44 секунды Это правильный способ
0
|
|||
|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
||||||||
| 02.11.2025, 10:22 [ТС] | ||||||||
0
|
||||||||
|
фрилансер
6455 / 5656 / 1129
Регистрация: 11.10.2019
Сообщений: 15,062
|
||||||
| 02.11.2025, 11:04 | ||||||
|
ADnD, вот абсолютно то же самое
вообще, тут, мне кажется, можно сильно упростить. Больно много проверок. Но оптимизатор теперь и сам справится
1
|
||||||
|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|||
| 02.11.2025, 11:16 [ТС] | |||
![]() P.S. Код исправил как вы посоветовали. Протестировал. Работает также
0
|
|||
| 02.11.2025, 11:16 | |
|
Помогаю со студенческими работами здесь
20
Корректное завершение работы консольного приложения Корректное освобождение памяти при принудительном завершении потока TThread Потоки и их корректное завершение Корректное завершение
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Символьное дифференцирование
igorrr37 13.02.2026
/ *
Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2).
Унарный минус обозначается как !
*/
#include <iostream>
#include <stack>
#include <cctype>. . .
|
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
|
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу,
и светлой Луне.
В мире
покоя нет
и люди
не могут жить в тишине.
А жить им немного лет.
|
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила»
«Время-Деньги»
«Деньги -Пуля»
|
|
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога
Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога
Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
|
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
|