5 июня 2018 г.

Задачка №24

Есть ли проблема в этом коде?

procedure DoSomething;
var
  S: String;
begin
  S := CalculateSomething;
  ShowMessage(S);
  Halt;
end;

Ответ.

11 комментариев :

  1. Нет, если винда NT. А вот в 95 вроде могла память не освободиться, после Halt.

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

    ОтветитьУдалить
  3. Ну аварийное, и что с того?

    ОтветитьУдалить
  4. Если ShowMessage вернёт управление раньше, чем закроется, Halt её убъёт. У меня ещё никогда не возвращала, правда...

    ОтветитьУдалить
  5. Там, сразу апосля ShowModal стоит Free

    ОтветитьУдалить
  6. Добрый день! А не подскажете есть ли обратная совместимость у проектов d2007 и d2006?

    ОтветитьУдалить
  7. Halt вызывает ExitProcess, так что все должно закончиться хорошо.
    Вот если бы вместо halt вызывался бы TerminateProcess - тут - да, могли бы быть проблемы, ведь второй, запустив механизм уничтожения, возвращает управление сразу же, в отличие от...

    ОтветитьУдалить
  8. Если в CalculateSomething или ShowMessage (точнее в Application.OnModalBegin или Application.OnModalEnd) генерируется исключение, то Halt не выполнится.
    Также обнаружил что, если в Application.OnModalBegin один раз генерируется исключение, то больше этот обработчик вызываться не будет. Наверное, надо было в TApplication.ModalStarted сначала вызывать FOnModalBegin(Self), а потом Inc(FModalLevel).

    ОтветитьУдалить
  9. Halt - страшная вещь, т.к. отрабатывает секции finalization... Данный пример демонстрирует всю разрушительную мощь сторонних эффектов при использовании глобального контекста.
    А в многопоточных приложениях, желательно еще перекрывать ExceptProc(== SysUtils.ExceptHandler), дабы не словить волну странных ошибок в незавершенных потоках.

    ОтветитьУдалить
  10. Для ответа на поставленный вопрос нужен код CalculateSomething.
    Подозреваю, что он порождает сто потоков, каждый из которых порождает сто процессов. Каждый из этих порожденных процессов смотрит, жив ли материнский процесс. Если нет, то каждый из этих потоков форматирует случайный логический диск. Поэтому кому-то, тому кто пока не собирается форматировать сотню случайных логических дисков на своем компьютере, может показаться, что проблемы в этом коде все-таки есть. Я бы рекомендовал такому осторожному человеку не спешить закрывать диалог в ShowMessage.

    ОтветитьУдалить
  11. С другой стороны, автор кода явно хотел, чтобы после закрытия ShowMessage программа завершила работу. Однако, как GunSmoker показал в предыдущем посте, сам код ShowMessage (впрочем, как и любой другой) весьма легко может быть поставлен в невозможные условия работы, например, испорченным стеком или таблицей импорта. Поэтому, автору, возможно, следовало бы написать так:
    procedure DoSomething;
    var
    S: String;
    begin
    S := CalculateSomething;
    try
    ShowMessage(S);
    finally
    Halt;
    end;
    end;

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и (опционально) ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

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

Примечание. Отправлять комментарии могут только участники этого блога.