initialization / finalization - требуется уточнение
Модератор: Модераторы
initialization / finalization - требуется уточнение
Столкнулся в коде с незнакомыми понятиями...
1) initialization
2) finalization
Правильно ли я понимаю что:
1) То что сказано после initialization - запуститься после старта программы? Или после обращения к данному юниту?
2) finalization - срабатывает перед выходом из программы?
Правильным ли будет ниже-приведенный код:
...
initialization
Form2.Create(Self);
finalization
Form2.Free;
end.
/
1) initialization
2) finalization
Правильно ли я понимаю что:
1) То что сказано после initialization - запуститься после старта программы? Или после обращения к данному юниту?
2) finalization - срабатывает перед выходом из программы?
Правильным ли будет ниже-приведенный код:
...
initialization
Form2.Create(Self);
finalization
Form2.Free;
end.
/
initialization выполняется до старта программы, finalization - после завершения. Если в программе подключены несколько модулей, секции инициализации исполняются в порядке объявления модулей, финализации - в обратном порядке.
Под программой я имею ввиду то, что находится между словами begin и end.
Добавлено спустя 3 минуты 38 секунд:
Под программой я имею ввиду то, что находится между словами begin и end.
Добавлено спустя 3 минуты 38 секунд:
The initialization block is used to initialize certain variables or execute code that is necessary for the correct functioning of the unit. The initialization parts of the units are executed in the order that the compiler loaded the units when compiling a program. They are executed before the first statement of the program is executed.
The finalization part of the units are executed in the reverse order of the initialization execution. They are used for instance to clean up any resources allocated in the initialization part of the unit, or during the lifetime of the program. The finalization part is always executed in the case of a normal program termination: whether it is because the final end is reached in the program code or because a Halt instruction was executed somewhere.
Спасибо за ответ, но возникли ещё вопросы:
Перевод: Они используются, например, для очистки любых ресурсов, выделенных в разделе инициализации устройства, или во время жизни программы.
Смущает последняя фраза из перевода: или во время жизни программы.
Как finalization работает во время жизни программы?
Перевод: Завершение части всегда выполняется в случае нормального окончания программы: то ли это потому, что конечная цель будет достигнута в коде программы или потому, что Остановиться, были выполнены команды где-то.
Из перевода невозможно понять, следующее:
Сработает ли finalization при принудительном вызове Halt посредине кода программы?
.
absdjfh писал(а):They are used for instance to clean up any resources allocated in the initialization part of the unit, or during the lifetime of the program.
Перевод: Они используются, например, для очистки любых ресурсов, выделенных в разделе инициализации устройства, или во время жизни программы.
absdjfh писал(а):The finalization part is always executed in the case of a normal program termination: whether it is because the final end is reached in the program code or because a Halt instruction was executed somewhere.
Перевод: Завершение части всегда выполняется в случае нормального окончания программы: то ли это потому, что конечная цель будет достигнута в коде программы или потому, что Остановиться, были выполнены команды где-то.
.
vitaly_l писал(а):Как finalization работает во время жизни программы?
Никак. Вы не правильно поняли фразу. Имеется ввиду, что в этой секции можно очищать все, что было выделено, например, в секции инициализации или во время работы программы.
vitaly_l писал(а):Сработает ли finalization при принудительном вызове Halt посредине кода программы?
Да, сработает. Перевод: секция финализации всегда выполняется в случае нормального завершения работы программы: как в случае достижения последнего end в коде программы, так и после выполнения инструкции Halt.
absdjfh писал(а):можно очищать все, что было выделено, например, в секции инициализации или во время работы программы.
Спасибо.
absdjfh писал(а):Да, сработает. как в случае достижения последнего end в коде программы, так и после выполнения инструкции Halt.
Спасибо.
И ещё раз громадное СПАСИБО!
.
-
NTFS
- постоялец
- Сообщения: 388
- Зарегистрирован: 05.11.2007 13:57:50
- Откуда: Краснодар
- Контактная информация:
Я рекомендую никогда, НИКОГДА не использовать в своих программах секции finalization и initialization. При написании мало-мальски сложной программы с десятком юнитов эти секции дают множество проблем. Если учесть еще, что исполнимый файл и операционная система совершенно по-разному реагирует на исключения в begin end и initialization, то вы рискуете огрести неизвестные неотслеживаемые ошибки, особенно у конечного пользователя.
Зачем вообще нужны эти секции, когда можно сделать так:
Все сказанное выше справедливо для любого компилятора Pascal (да-да, Delphi тоже), но для FPC с его вечными Segmentation fault и прочими радостями - вдвойне.
Зачем вообще нужны эти секции, когда можно сделать так:
Код: Выделить всё
program MyBestProg ;
begin
InitAllMyObjectsInCorrectOrder() ;
try
MainCode() ;
finally
UnInitAllMyObjectsInCorrectOrder() ;
end ;
end.
Все сказанное выше справедливо для любого компилятора Pascal (да-да, Delphi тоже), но для FPC с его вечными Segmentation fault и прочими радостями - вдвойне.
- alexs
- долгожитель
- Сообщения: 4069
- Зарегистрирован: 15.05.2005 23:17:07
- Откуда: г.Ставрополь
- Контактная информация:
NTFS писал(а):Я рекомендую никогда, НИКОГДА не использовать в своих программах секции finalization и initialization
Ну не надо быть столь категоричным
Как и всякий инструмент, его надо использовать продумано.
Я, например, пользуюсь им для объявления и очистки переменных, которые 100% не видны из других модулей.
Т.е. - допустим у меня есть какой либо список, в котором надо вести учёт каких либо объектов.
Создаём его при инициализации, освобождаем выделенную под него память при завершении.
А во время работы доступ к списку идёт опосредовано - только через вызов соответствующих процедур.
Удобно. Не нужно лишний раз объекты делать для вещей, где объекты не нужны. И управляемость хорошая.
NTFS писал(а):Зачем вообще нужны эти секции, когда можно сделать так:Код: Выделить всё
program MyBestProg ;
begin
InitAllMyObjectsInCorrectOrder() ;
try
MainCode() ;
finally
UnInitAllMyObjectsInCorrectOrder() ;
end ;
end.
Т. е. вы предлагаете вместо секции initialization, написанной в модуле X, использовать процедуру инициализации, написанную в том же модуле?
Это может оказаться более рискованным, чем проблемы исключений в программе и в initialization. Часто модуль используется во многих программах. Вы предлагаете вставлять такой блок в каждую вновь создаваемую программу? Нет, я точно могу забыть про такие блоки
Добавлено спустя 3 минуты 56 секунд:
Представьте, что к вашему совету прислушались разработчики FPC. И теперь вам в каждой программе нужно вызывать такой код:
Код: Выделить всё
{ get some helpful informations }
GetStartupInfo(@startupinfo);
SysResetFPU;
if not(IsLibrary) then
SysInitFPU;
{ some misc Win32 stuff }
hprevinst:=0;
if not IsLibrary then
SysInstance:=getmodulehandle(nil);
MainInstance:=SysInstance;
{ pass dummy value }
StackLength := CheckInitialStkLen($1000000);
StackBottom := StackTop - StackLength;
cmdshow:=startupinfo.wshowwindow;
{ Setup heap }
InitHeap;
SysInitExceptions;
{ setup fastmove stuff }
fpc_cpucodeinit;
SysInitStdIO;
{ Arguments }
setup_arguments;
{ Reset IO Error }
InOutRes:=0;
ProcessID := GetCurrentProcessID;
{ threading }
InitSystemThreads;
{ Reset internal error variable }
errno:=0;
initvariantmanager;
initwidestringmanager;
{$ifndef VER2_2}
initunicodestringmanager;
{$endif VER2_2}
InitWin32Widestrings;
DispCallByIDProc:=@DoDispCallByIDError;Или процедуру InitSystemUnit (ну или как ее назвать по-другому).
NTFS писал(а):то вы рискуете огрести неизвестные неотслеживаемые ошибки, особенно у конечного пользователя.
Спасибо. Возможно именно с этим я и столкнулся, т.к. подопытный мне unit начал функционировать после внесения в его функцию
Create строчки inherited Create; из этого можно предположить что initialization - действительно работает криво, т.к. у разработчика - функция работала. Но не факт, try finally end идентично решат проблему...
Ради чистоты эксперимента - попробую заменить на try finally end...
Я это не использую в коде, я просто пытаюсь восстановить дееспособность ряда функций в GLScene и там столкнулся с неизвестными мне
функциями. Кстати GLScene - очень хороший продукт, но судя по всему некоторый код там устарел. Но зато, то что работает - выполняет свои функции на 100++1% и довольно надёжно (надеюсь).
Похоже на правду... Выше описан эксперимент - попробую, о результате расскажу. Если NTFS - прав, то код заработает (либо сбой был в другом месте).alexs писал(а):Как и всякий инструмент, его надо использовать продумано. для объявления и очистки переменных, которые 100% не видны из других модулей.
absdjfh писал(а):Представьте, что к вашему совету прислушались разработчики FPC. И теперь вам в каждой программе нужно вызывать такой код:
Лично я не вызываю в каждой программе функцию initialization - соответственно Ваш пример нечестный. Хотя сам подход использования initialization и finalization - по идее более правильный и я также априори не могу согласиться с NTFS в том что try finally end... работают корректнее нежели initialization и finalization...
Истину - можно проверить только на чистом эксперименте.
.
vitaly_l писал(а):Лично я не вызываю в каждой программе функцию initialization
Каждая ваша программа (если у вас система win32) вызывает такой код перед своим выполнением. Это секция инициализации модуля System.
absdjfh писал(а):Это секция инициализации модуля System
Это ложь. В моём модуле System нет функции initialization. Но там есть код который Вы привели в качестве примера...
Блок begin end в модуле - это секция инициализации. Из документации:
An initialization section by itself (i.e. without finalization) may simply be replaced by a statement block. That is, the following:
Initialization
InitializeUnit;
end.
is completely equivalent to
Begin
InitializeUnit;
end.
vitaly_l писал(а):Истину - можно проверить только на чистом эксперименте.
При попытке заменить initialization finalization на try finally end - модуль отказался компилироваться и Лазарус откровенно выругался.
Думаю на этом закончить эксперимент, т.к. Лазарус - имеет неоспоримый приоритет и когда он отказывается компилировать любые потуги бессмысленны.
absdjfh писал(а):Блок begin end в модуле - это секция инициализации.
Эквивалент так эквивалент... Будем знать и пользоваться.
Ещё раз - большое СПАСИБО ВСЕМ!
.
vitaly_l писал(а):При попытке заменить initialization finalization на try finally end - модуль отказался компилироваться и Лазарус откровенно выругался.
Думаю на этом закончить эксперимент, т.к. Лазарус - имеет неоспоримый приоритет и когда он отказывается компилировать любые потуги бессмысленны.
Вы прямо так пословно и заменяли?
Лично я советовал бы вам использовать то, что кажется вам удобным, а за дополнительными разъяснениями относительно блоков initialization/finalization обращаться непосредственно к NTFS.
absdjfh писал(а):в примере NTFS этот блок должен быть в программе, а не модуле
Внимание - обратил...
Добавлено спустя 1 минуту 15 секунд:
absdjfh писал(а):Вы прямо так пословно и заменяли?
Да именно так, а разве надо иначе?
