Просмотр сообщений

В этом разделе можно просмотреть все сообщения, сделанные этим пользователем.


Сообщения - vlad

Страницы: 1 ... 91 92 [93]
1381
Общий раздел / Re:ASSERT
« : Февраль 19, 2011, 09:48:06 pm »
Этот код я назначил сам, и он имеет смысл только для меня, как для автора программы. От пользователя, у которого сбойнула моя программа, мне нужен только этот код и больше ничего.

Неправда. Первое, что вы захотите от пользователя в случае какой-либо ошибки - это версия.

По памяти, в документации на КП/BB вроде определены стандартные коды, и определён также дииапазон кодов для использования по своему усмотрению. Этими спецификациями я не пользуюсь.

Что лишний раз показывает бессмысленность подобного рода спецификаций...

Представьте, что у Вас много клиентов, которые пользуются различными версиями Вашей программы, и они присылают Вам отчёты, что в такой-то строчке сработал ассерт. В данной ситуации код ошибки надёжнее, потому что в различных версиях программы нумерация строк может поплыть.

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

Цитировать
В моём примере "199" и есть код ошибки.

Не совсем. Его нельзя нормально обработать потребителю вашего модуля. Если опять говорить о варианте сторонних модулей без исходников...

1382
Общий раздел / Re:ASSERT
« : Февраль 19, 2011, 03:41:38 pm »
А вот сообщение консольного компилятора XDS:
#RTS: unhandled exception #199: ASSERT(FALSE, 199) И всё! Только номер и спасает ("199" в примере).

Это такой тонкий стеб или реально каждый оберонщик знает что такое "199"? %)

Цитировать
Да, и ещё. Ассерт - это всё-таки языковое средство, а не фенечка IDE. Раз язык вводит ассерты, то должен и предоставить средство для их идентификации. Второй параметр в стандартной процедуре ASSERT, на мой взгляд, оправдан.

Дык, я ж говорю - стэк и номер строки идентифицируют намного лучше какого-то "199". По поводу модулей без исходников, но со строковыми ресурсами - да, этот параметр приобретает какой-то смысл. Но мне кажется, что в этом случае еще лучше сработал бы банальный возврат кода ошибки.

1383
Общий раздел / ASSERT
« : Февраль 19, 2011, 04:59:22 am »
Навеяно недавним просмотром ББ'ых исходников... А в чем глубокий смысл второго параметра ББ'ого ASSERT'а? Нигде таких ассертов нет :) В смысле все полезное в стэке и в номере строки, нет? :) Зачем эта лишняя сущность в языке, славящимся отсутствием всего лишнего?

1384
В предыдущий раз недостаточно точно выразил мысль, поскольку f1..f7, это на деле не неделимые функции. Так будет точнее
Type t1, t2;

if (c1) {
   Type t3 = f0(p1, p2);    
   t1 = f1(p1, t3);
   t2 = f2(p2, t3);
} else {
   t1 = f3(p3);
}

...

if (c1 && c2) {
   f5(t1);
   f6(t2);
} else {
   f7(t1);
}

Да, это интереснее :) Первый кусок кода:
if (c1) {
   Type t3 = f0(p1, p2);  
   t1 = f1(p1, t3);
   t2 = f2(p2, t3);
} else {
   t1 = f3(p3);
}

выносим в функцию, которая возвращает t1 и "опциональное" t2. Тогда оставшийся кусок будет выглядеть так:

(Type t1, TypeOptional t2) = f();
...
if (t2.initialized() && c2) {
   f5(t1);
   f6(t2); // здесь t2 гарантировано не "пустое", компилятор про это знает, потому что выше произошла проверка/приведение типа от TypeOptional к Type
} else {
   f7(t1);
}

1385
...

Type t1, t2;

if (c1) {
    t1 = f1(p1);
  t2 = f2(p2);
} else {
    t1 = f3(p3);
}

...

if (c1 && c2) {
 f5(t1);
   f6(t2);
} else {
 f7(t1);
}

Сразу замечу, что компилятору, проверяющему инициализацию, c оригинальным кодом будет непросто разобраться :) Вот мой "преобразованный" вариант для критики:

Type t1 = с1 ? f1(p1) : f3(p3);

...

if (c1 && c2) {
   f5(t1);
        Type t2 = f2(p2);
        f6(t2);
} else {
 f7(t1);
}

1386
Я думаю, что нужно предоставить программисту удобную возможность проинициализировать переменную при объявлении и напомнить ему, если это не сделано. Но принуждать к инициализации не нужно. Иначе в рантайме уже не удастся сгенерировать и обработать исключение, когда действительно осмысленная инициализация не прошла. Программа будет утверждать, что "всё хорошо, прекрасная маркиза", хотя на самом деле это не так.

Давайте зайдем от обратного :) Придумайте пример, когда вы не можете осмысленно инициализировать переменную сразу. Мы над ним помедитируем :) Рассмотрим достоинства и недостатки.

1387
К сожалению Ява, в отличае от например Ады, не позволяет определить тип ненулевой ссылки. А тут бы оно было бы очень полезно. Поэтому среди Адовцев Ява считается языком маленьким и слабеньким :-)

Угу. Глядя на жабовский/обероновский код, в который пришел указатель, никогда не сможешь сказать, что здесь никогда не будет "null dereference exception". Потому что нет _типа_ ненулевых указателей.

1388
Я против такой имитации решения проблемы.  :-\\

Это похоже на то, как действуют пользователи MS Access. Там есть поля, которые программист делает обязательными для заполнения. Хитро...умные пользователи ставят пробел, и программа считает, что всё OK. Ну и кому от этого польза? Реальная-то информация не введена, а введена галиматья!

Нет. Язык дает средство сделать код надежнее/понятнее/эффективнее. Если программист не хочет этим воспользоваться - то тут языком дело не исправишь. Ключевое отличие от Access в том, что там есть разделение на программиста, который думает, что поле обязательно и требует ввести туда значение, и пользователя, который знает, что на самом деле оно не обязательно и вбивает туда мусор :) В случае ЯП такого разделения нет. Программу пишет программист и он же вбивает осмысленное значение, чтобы яснее выразить свою мысль. Для читающего программиста инициализация делает код понятнее.

Вместо того, чтобы напрячь разработчика компилятора, мы, получается, заставляем прикладного программиста вводить бессмысленные значения, чтобы только компилятор не ругался! На самом деле компилятор должен найти те переменные, которые заведомо никогда не инициализируются. Если же в процессе исполнения программы до инициализации просто не дойдет дело, то тогда должно генерироваться исключение.

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

P.S. Еще хочу сказать, что такой подход (тотальная инициализация и ненулевые указатели) уже несколько лет успешно обкатан мной лично на практике. Реально "ненужных" присваиваний (нулевых) чрезвычайно мало - они возникают у меня только на стыке с Win API, когда какая-то переменная будет заведомо проинициализирована вызовом функции, но я ее все равно инициализирую в 0, чтобы не нарушать стиль. Проблема только в том, что в случае С++ это вопрос стиля - компилятор позволяет так писать, но не требует.

1389
Тут есть отличие -- знаем мы что оно зациклилось, или не знаем. Если знаем, тогда ждать смысла не имеет, надо убить (если зациклилось), если мы гарантировано знаем что алгоритм конечный, то можем подождать. Более того, можем как-то проследить процесс исполнения и что-то спрогнозировать. Т.е. процесс получаем управляемый.

С точки зрения пользователя программы все равно - зависла она на совсем или сделает свою работу через пару миллиардов лет. И так и так - глючит :)

P.S. Хотя, конечно, иметь гарантии завершимости на этапе компиляции было бы полезно. Сколько-то ошибок/опечаток не пролезло бы.

1390
Т.е. программа должна получаться верна по построению. Не должно быть зацикливаний, выходов за границы, численных переполнений.

А чем, собственно, зацикливание отличается от просто очень долгого алгоритма? С точки зрения конечного результата в виде "зависания".

1391
Цитата: Сергей Прохоренко
Уже полгода на моем рабочем столе лежит презентация The Next Mainstream Programming Language: A Game Developer’s Perspective - крик души разработчика игр. Лежит как напоминание о том, что хороший структурный редактор должен соответствовать этим ясно выраженным потребностям. Должен признать, что предложенные автором решения мне понравились. А компьютерные игры - это передовой край Computer Science, эталон пригодности инструментального программного обеспечения к решению сложных задач.

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

По поводу нулевых указателей и неинициализированных переменных. Я уже выступал на оригинальном форуме (http://forum.oberoncore.ru) и наверняка есть ЯП в которых эта проблема в каком то виде решена, но если подытожить применительно к оберону и структурному редактору, то основные тезисы такие:
- Неинициализированных переменных нет, потому что объявление переменной совмещено с ее инициализацией синтаксически. A-ля VAR i: INTEGER := 3.
- Указатели по умолчанию ненулевые (обязаны быть проинициализированы реальным объектом или другим ненулевым указателем).
- Можно объявить нулевой указатель. Это другой тип, совместимый с ненулевым указателем в одну сторону: ненулевой указатель может быть приведен к нулевому, но не наоборот. Нулевой указатель не может быть разыменован.
- Для получения ненулевого указателя из нулевого есть специальная синтаксическая конструкция вроде обероновской проверки/приведения типа с помощью WITH. Если проверка сработала, то выполняется ветка кода, где "виден" ненулевой указатель.

Страницы: 1 ... 91 92 [93]