Re[6]: Причина не внутри модуля, а вне его
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 07.12.05 13:32
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Нет. Как раз у него и срабатывают assert на этапе разработки. Собственно он и есть пользователь assert. В дальнейшем они не нужны.


Наоборот. Посмотрите на эту ситуацию "наизнанку" То что ассерт размещен в его коде — не означает что в его срабатывании виноват он. Ошибка снаружи.

Пример.
Я разработал компонент, который предназначен для вычисления квадратного корня из числа:
DEFINITION MySuperCalculator;
  
  PROCEDURE Sqrt (x: REAL): REAL; (* precondition x >= 0, 20 *)

END MySuperCalculator.

Я ЗАПРЕТИЛ впихивать внутрь моего компонента отрицательные числа. Для того чтобы мой запрет не был очередным "последним китайским предупреждением", я сказал, что тот кто попытается впихнуть в мой компонент отрицательное число, тот пожалеет об этом — здорово получит по мозгам, так как MySuperCalculator.Sqrt(x), я "заминировал ассертом" на проверку предусловия ASSERT(x >= 0)
Вот исходный код моего модуля:
MODULE MySuperCalculator;

  IMPORT Math;

  PROCEDURE Sqrt* (x: REAL): REAL;
  BEGIN
    ASSERT(x >= 0, 20); (* <-- это оборона от внешних по отношению к моему компоненту ошибок *)
    RETURN Math.Sqrt(x)
  END Sqrt;

END MySuperCalculator.

Этот ассерт направлен не против меня, а против других программистов, которые будут использовать мой компонент.
Re[13]: Sqrt - хороший пример компонента обороняющегося от о
От: minorlogic Украина  
Дата: 07.12.05 13:38
Оценка: 1 (1) +1
Тогда подрезюмирую.

1. Разработчики внесли ASSERT в свои библиотеки подразумевающий другую идеологию использования, чем это общепринято испторически.

2. НИКАКИЕ выводы сделанные о использовании ASSERT в BlackBox нельзя перносить на другие языки/платформы.

3. Стыд разработчикам , что они использовали такое узнаваемое слово как "ASSERT" в ключе отличном от общепринятого.
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[13]: Sqrt - хороший пример компонента обороняющегося от о
От: MShura  
Дата: 07.12.05 13:42
Оценка:
MS>>ASSERT просто обрушит программу не позволяя сохранить данные.

СГ>Это смотря какую программу. На Си/С++ — легко. В Блэкбоксе на Component Pascal — ничего подобного, там просто снимется выполнение этой ошибочной команды. Данные никуда пропадать от этого не обязаны — смотря как напишешь. Но не зависимо от этого, в любом случае — сработавший ассерт — это ошибка в программе и её надо переписывать.


Ладно я понимаю, как можно "снять выполнение ошибочной комманды" если значение Sqrt() нигде не сохраняется.
А если Sqrt() используется в выражении, то как можно "снять выполнение ошибочной комманды"?
Re[7]: Причина не внутри модуля, а вне его
От: GlebZ Россия  
Дата: 07.12.05 13:57
Оценка: +1
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Этот ассерт направлен не против меня, а против других программистов, которые будут использовать мой компонент.

Ага. А теперь посмотрим тот же код.
double MySqrt(double x)
{
  ASSERT(x>0);//это внутренняя ошибка программиста пишущего модуль.
                            //при ее срабатывании поднимается отладчик, и этот программист
                            //может посмотреть что случилось
    if (x>0)
    throw new MyException("вы кормите MySqrt отрицательными значениями");//а вот это
                            //сообщение для некорректного программиста модуля
                            //ему будет вполне понятно что случилось
    return Math.Sqrl(x);
}

А теперь представь себе что это рассчет матриц в полумегабайтном коде и ошибка произошла на 10 уровне вложенности.
void CountMatrix()
{
  try
    {
    }
    catch(MyException e)
    {
      Logger.Write(e);
      throw new MyException("Произошла внутренняя ошибка. Бери трубку и звони производителям", e);
    }
}


Теперь понятна разница между ASSERT и EXCEPTION? Исключение мы можем представить пользователю в понятном виде, ассерт — никогда.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[14]: Sqrt - хороший пример компонента обороняющегося от о
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 08.12.05 08:41
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Ладно я понимаю, как можно "снять выполнение ошибочной комманды" если значение Sqrt() нигде не сохраняется.

MS>А если Sqrt() используется в выражении, то как можно "снять выполнение ошибочной комманды"?

Как снять выполнение команды не потеряв при этом данные?

Интерфейс модуля:
DEFINITION MyModule;

 PROCEDURE Command1;
 PROCEDURE Command2

END MyModule.

Исходный текст модуля:
MODULE MyModule;

  IMPORT 
    ...

  TYPE
    MyData = ...

  VAR
    data: MyData;

 PROCEDURE Init;
 BEGIN (* инициализация данных *)
 END Init;

 PROCEDURE Command1*;
 BEGIN (* код команды 1, выполняющей операцию с данными data *)
 END Command1;

 PROCEDURE Command2*;
 BEGIN (* код команды 2, выполняющей операцию с данными data *)
 END Command2;

 PROCEDURE Close;
 BEGIN (* закрытие данных *)
 END Close;

BEGIN
  Init
CLOSE
  Close  
END MyModule.


Выполняя процедуры: MyModule.Command1, MyModule.Command2 как команды, мы не потеряем данные data даже если выполнение этих команд будет аварийно завершено.

Команда — это средство предоставляемое системой. Фактически это есть запуск процедуры по её (текстовому) имени "MyModule.MyCommand" (допустимые типы аргументов процедуры предопределены системой, в частности — любую процедуру без параметров можно выполнять как команду). Запуск команды делается системой внутри системной ловушки, так что если внутри процедуры происходит "авария", то "исключение" ловится системной ловушкой. Это всё равно что в Windows/Linux в командной строке набрать имя программы и нажать Enter — программа будет запущена по имени, а в оберон-системах, в любом текстовом документе пишете имя процедуры: MyModule.MyCommand, выделяете мышью и нажав на соответсвующий пункт меню запускаете эту процедуру на выполнение как команду (разумеется есть масса других способов инициировать выполнение команды, в том числе и в "фоновом" режиме — не одной же коммандной строкой ограничиваться). Если модуль MyModule не был загружен в память, то он автоматически загружается. Выгрузить его можно потом выполнив другую специальную системную команду. Команда в оберон-системе в этом смысле похожа на программу в Windows/Linux. Снять выполнение текущей команды (если она что-то долго выполняется и быть может зависла) можно нажав на клавиатуре кнопку Break (аналог Ctrl+Alt+Del в Windows).
Re[8]: Причина не внутри модуля, а вне его
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 08.12.05 08:52
Оценка: :)))
Здравствуйте, GlebZ, Вы писали:

GZ>Теперь понятна разница между ASSERT и EXCEPTION? Исключение мы можем представить пользователю в понятном виде, ассерт — никогда.


Это у Вас в С++ так, а у нас в Component Pascal подругому — exteption нету, а вместо них есть ASSERT

Ну, а что касается пользователя, то единственный понятный вид сообщения об ошибке для него таков:

"В программе обнаружена ошибка, поэтому использование программы далее — бессмысленно. Обратитесь к разработчику."

всё остальное ему до лампочки...
Re[15]: Sqrt - хороший пример компонента обороняющегося от о
От: Кодёнок  
Дата: 08.12.05 08:52
Оценка: +1
Здравствуйте, Сергей Губанов, Вы писали:

MS>>Ладно я понимаю, как можно "снять выполнение ошибочной комманды" если значение Sqrt() нигде не сохраняется.

MS>>А если Sqrt() используется в выражении, то как можно "снять выполнение ошибочной комманды"?

СГ>Как снять выполнение команды не потеряв при этом данные?


СГ>Команда в оберон-системе в этом смысле похожа на программу в Windows/Linux. Снять выполнение текущей команды (если она что-то долго выполняется и быть может зависла) можно нажав на клавиатуре кнопку Break (аналог Ctrl+Alt+Del в Windows).


Интересно.

А если эта команда вызывает 10 других команд, или рекурсивно саму себя, что именно будет прервано? Как поведут себя внешние по отношению к этой команды?

Что будет, если вызывающий ожидает от команды возвращаемого значения (через var-параметр или результат функции), как ему продолжить выполнение, если результата он не получил? Как он узнает, что было прерывание и результат не получен?
Re[9]: Причина не внутри модуля, а вне его
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.12.05 08:58
Оценка: +5
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Это у Вас в С++ так, а у нас в Component Pascal подругому — exteption нету, а вместо них есть ASSERT


Тогда тему нужно было обзывать "Почему нельзя отключать ASSERT-ы Component Pascal в релизе"
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Почему нельзя отключать ASSERT-ы в релизе
От: 0rc Украина  
Дата: 08.12.05 09:50
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>И что это за задачи такие?


Первое, что пришло в голову, например марсоход NASA
... << RSDN@Home 1.2.0 alpha rev. 619>>
Re[4]: Почему нельзя отключать ASSERT-ы в релизе
От: Pzz Россия https://github.com/alexpevzner
Дата: 08.12.05 11:01
Оценка:
0rc wrote:
>
> Pzz>И что это за задачи такие?
>
> Первое, что пришло в голову, например марсоход NASA

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

Что должна делать программа марсохода при обнаружении _внутренней
ошибки_ на Марсе, когда ASSERT отключен (а ошибка не отключена)?
Posted via RSDN NNTP Server 2.0
Re[5]: Почему нельзя отключать ASSERT-ы в релизе
От: 0rc Украина  
Дата: 08.12.05 11:26
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Что должна делать программа марсохода при обнаружении _внутренней

Pzz>ошибки_ на Марсе, когда ASSERT отключен (а ошибка не отключена)?

А если ASSERT включен на Марсе, что тогда, легче будет?
Я бы не применял в таких программах вообще ASSERT и проектировал бы с таким важным условием.
Re[5]: Почему нельзя отключать ASSERT-ы в релизе
От: Cyberax Марс  
Дата: 08.12.05 11:41
Оценка:
Pzz wrote:

> Что должна делать программа марсохода при обнаружении _внутренней

> ошибки_ на Марсе, когда ASSERT отключен (а ошибка не отключена)?

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

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[6]: Почему нельзя отключать ASSERT-ы в релизе
От: Кодёнок  
Дата: 08.12.05 11:48
Оценка: :))) :))
Здравствуйте, Cyberax, Вы писали:

>> Что должна делать программа марсохода при обнаружении _внутренней

>> ошибки_ на Марсе, когда ASSERT отключен (а ошибка не отключена)?

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


...командировать специалиста...
Re[16]: Sqrt - хороший пример компонента обороняющегося от о
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 08.12.05 14:38
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Интересно.


Кё>А если эта команда вызывает 10 других команд, или рекурсивно саму себя, что именно будет прервано? Как поведут себя внешние по отношению к этой команды?


Кё>Что будет, если вызывающий ожидает от команды возвращаемого значения (через var-параметр или результат функции), как ему продолжить выполнение, если результата он не получил? Как он узнает, что было прерывание и результат не получен?


1) Это процедура может вызвать саму себя, но это будут вызовы в контексте одной и той же команды.
2) Никакого возвращаемого значения у команды нет.

В Обероне задачи бывают двух типов: интерактивные и фоновые. Команда — это интерактивная задача, её исполнение инициирует непосредственно пользователь (отдаёт команду — отсюда и название). Фонововые задачи запускает (ставит в очередь исполнения) либо сам пользователь, либо другие задачи (команды), в том числе и фоновые. Ситуация описанная Вами, по всей видимости, решается через фоновые задачи. Например так: одна задача ставит в очередь задач другую и засыпает, потом просыпается и смотрит что произошло. В Блэкбоксе фоновые задачи представлены расширениями типа Services.Action
DEFINITION Services;

  CONST
    immediately = -1;
    now = 0;

    resolution = 1000;

  TYPE
    Action = POINTER TO ABSTRACT RECORD 
      (a: Action) Do-, NEW, ABSTRACT
    END;

  ...

  PROCEDURE DoLater (a: Action; notBefore: LONGINT);
  PROCEDURE RemoveAction (a: Action);

  ...

  PROCEDURE Ticks (): LONGINT;

  ...

END Services.

Метод Action.Do — это квант работы задачи (многозадачность в Блэкбоксе кооперативная), он выполняется в окружении системной ловушки и если в нём произойдёт авария, то эта задача будет снята. Задача должна каждый раз себя устанавливать заново после каждого "такта" своей работы: Services.DoLater(task, Services.Ticks() + milliseconds);
Re[17]: Sqrt - хороший пример компонента обороняющегося от о
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 08.12.05 14:41
Оценка:
СГ>Задача должна каждый раз себя устанавливать заново после каждого "такта" своей работы: Services.DoLater(task, Services.Ticks() + milliseconds);

Естественно, только если ей это нужно...
Re[14]: Sqrt - хороший пример компонента обороняющегося от о
От: AVC Россия  
Дата: 09.12.05 23:27
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Тогда подрезюмирую.


M>1. Разработчики внесли ASSERT в свои библиотеки подразумевающий другую идеологию использования, чем это общепринято испторически.


M>2. НИКАКИЕ выводы сделанные о использовании ASSERT в BlackBox нельзя перносить на другие языки/платформы.


M>3. Стыд разработчикам , что они использовали такое узнаваемое слово как "ASSERT" в ключе отличном от общепринятого.


Стыд и позор также Стиву Макконелу за такие вот мысли:

По мере возможности делайте интерфейсы программными, а не семан-
тическими Каждый интерфейс состоит из программной и семантической
частей. Первая включает типы данных и другие атрибуты интерфейса, которые могут
быть проверены компилятором. Вторая складывается из предположений об ис-
пользовании интерфейса, которые компилятор проверить не может. Семантический
интерфейс может включать такие соображения, как «Метод А должен быть выз-
ван перед Методом B» или «Метод А вызовет ошибку, если переданный в него Эле-
мент Данных 1 не будет перед этим инициализирован». Семантический интерфейс
следует документировать в комментариях, но вообще интерфейсы должны как
можно меньше зависеть от документации. Любой аспект интерфейса, который не
может быть проверен компилятором, является потенциальным источником оши-
бок. Старайтесь преобразовывать семантические элементы интерфейса в програм-
мные, используя утверждения (assertions) или иными способами.

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[15]: Sqrt - хороший пример компонента обороняющегося от о
От: Курилка Россия http://kirya.narod.ru/
Дата: 10.12.05 10:33
Оценка:
А вот такой фрагмент тебя не заставляет задуматься:

Любой аспект интерфейса, который не
может быть проверен компилятором, является потенциальным источником ошибок.

?

assert в рантайме не есть проверка компилятором, тебе так не кажется?
Имхо Стиву как раз ни разу не стыд и не позор.
Re[15]: Sqrt - хороший пример компонента обороняющегося от о
От: Mikhail Polykovsky Россия  
Дата: 10.12.05 12:26
Оценка:
AVC>Стыд и позор также Стиву Макконелу за такие вот мысли:
AVC>

AVC>... Старайтесь преобразовывать семантические элементы интерфейса в програм-
AVC>мные, используя утверждения (assertions) или иными способами.


Есть практические рекомендации, как этого достигать? С примерами?
Re[16]: Sqrt - хороший пример компонента обороняющегося от о
От: AVC Россия  
Дата: 10.12.05 12:52
Оценка:
Здравствуйте, Курилка, Вы писали:

К>А вот такой фрагмент тебя не заставляет задуматься:

К>

К>Любой аспект интерфейса, который не
К>может быть проверен компилятором, является потенциальным источником ошибок.

К>?

К>assert в рантайме не есть проверка компилятором, тебе так не кажется?

К>Имхо Стиву как раз ни разу не стыд и не позор.

Я что-то переврал?
В приведенной цитате Макконнелла не содержалось совета использовать утверждения?
Или я отрицал важность статического контроля типов?
В чем претензия?

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[16]: Sqrt - хороший пример компонента обороняющегося от о
От: AVC Россия  
Дата: 10.12.05 12:53
Оценка:
Здравствуйте, Mikhail Polykovsky, Вы писали:


AVC>>Стыд и позор также Стиву Макконелу за такие вот мысли:

AVC>>

AVC>>... Старайтесь преобразовывать семантические элементы интерфейса в програм-
AVC>>мные, используя утверждения (assertions) или иными способами.


MP>Есть практические рекомендации, как этого достигать? С примерами?


Да, есть.
См. главы 11 и 12 книги Мейера "Объектно-ориентированное конструирование программных систем".
Там вводится понятие Design By Contract (проектирование по контракту).
А одним из примеров в 12-й главе является как раз функция вычисления квадратного корня sqrt(x).

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.