crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

Litkevich Yuriy
  опции профиля:
сообщение 21.4.2010, 11:57
Сообщение #1


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


у меня возник вопрос - "а хорошо ли программе падать?"

Есть перегруженный оператор [], в него передаётся индекс, и внутри оператора сделан assert на случай выхода индекса за границы разрешённого диаппазона.

Вроде так многие делают. Но правильно ли это?

Может правильнее поступать как-то иначе?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
3 страниц V   1 2 3 >  
Начать новую тему
Ответов (1 - 23)
DIMEDROLL
  опции профиля:
сообщение 21.4.2010, 12:05
Сообщение #2


Участник
**

Группа: Участник
Сообщений: 165
Регистрация: 28.9.2008
Из: Киев
Пользователь №: 304

Спасибо сказали: 23 раз(а)




Репутация:   0  


Цитата(Litkevich Yuriy @ 21.4.2010, 11:57) *
Может правильнее поступать как-то иначе?

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

Добавлено:
ИМХО ассерт - лучший друг программиста, ассертить можно все на что опираешься(напрмер, "эта переменная не должна быть ниже нуля"): входящие данные, выходящие данные, указатели, результаты connect, а уж тем более индексацию массивов... Зачастую, с помощью ассертов я находил такие баги что с дебаггером искал бы не один час. И бывало что с дебаггером сидел пол для, что бы обнаружить запись на 1 значение дальше конца массива.
Но не надо забывать о чистоте кода, если все и везде ассертить выйдет каша в коде,

Сообщение отредактировал DIMEDROLL - 21.4.2010, 12:15
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 21.4.2010, 12:41
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


вообще я всюду стараюсь использовать не просто int, а собственный тип данных, например так:
enum MyType{
    Val_1,
    Val_2
}
setType(MyType value);
MyType type();
это позволяет при программировании защитится от случайных входных значений. Но с индексами так не получается работать. И к сожалению в С\С++ нет типа диаппазона

Я вроде пытаюсь себя дисциплинировать такими вещами:
if (i < foo.size()) var = foo[i];
else do_anything();
но к сожалению тоже не всегда применяю, часто потому-что не могу быстро решить, что делать.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 21.4.2010, 13:01
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


IMHO, в операторе [] выход за пределы контейнера это по любому ошибка в коде программы. Ввод пользователя должен быть проверен еще до входа в этот метод. Такие ошибки должны отслеживаться еще на этапе отладки. Т.е. assert вполне удовлетворяет этим условиям, к тому же в релизе мы избавляемся от кода проверки.
Хотя, для особо дружественных программ можно использовать исключение, и при его возникновении сообщать пользователю, что произошла внутренняя ошибка # ... и ему нужно связаться с разработчиками.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 21.4.2010, 13:10
Сообщение #5


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


в случае источником индекса со стороны пользователя, сравнительно просто. А в случае если источник, информация пришедшая с коммуникационного ресурса, уже не так просто, разумеется касяк где-то в коде, в алгоритме. И всплывает не однозначно, может месяцами себя ни как не проявлять при непрерывной работе ПО.

И Ассерт, здесь не информативен, т.к. в релизе кроме как в консоль он ничего не пишет, а её никто не видит. Просто "Бац и программа вылетела"
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 21.4.2010, 13:21
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Все внешние данные, не важно откуда они приходят, должны быть проверенны еще до оператора []. По любому. :)
assert в этом операторе, только для программиста и говорит о том, что он где-то выше забыл проверить индекс.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 22.4.2010, 7:27
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Цитата(Litkevich Yuriy @ 21.4.2010, 16:41) *
...И к сожалению в С\С++ нет типа диаппазона...

boost::range
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.4.2010, 8:35
Сообщение #8


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(BRE @ 21.4.2010, 16:01) *
IMHO, в операторе [] выход за пределы контейнера это по любому ошибка в коде программы. Ввод пользователя должен быть проверен еще до входа в этот метод. Такие ошибки должны отслеживаться еще на этапе отладки. Т.е. assert вполне удовлетворяет этим условиям, к тому же в релизе мы избавляемся от кода проверки.
Хотя, для особо дружественных программ можно использовать исключение, и при его возникновении сообщать пользователю, что произошла внутренняя ошибка # ... и ему нужно связаться с разработчиками.

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

Цитата(Tonal @ 22.4.2010, 10:27) *
Цитата(Litkevich Yuriy @ 21.4.2010, 16:41) *
...И к сожалению в С\С++ нет типа диаппазона...

boost::range

да, тоже вариант: использование более надёжных объектов для хранения данных. у буста есть структуры для хранения произвольных данных, для обозначения "не числа" (т.е. переменная может содержать информацию, что её значение не валидно) и т.п. так что осваивайте и используйте на здоровье.

Сообщение отредактировал Iron Bug - 22.4.2010, 8:32
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 22.4.2010, 9:01
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Iron Bug @ 22.4.2010, 9:35) *
вот тоже так думаю. и "особая дружественность" тут ни при чём. любой эксепшн должен обрабатываться и не приводить к обрушению программы. это ненормальное программирование, если программист позволяет своей программе просто так взять и рухнуть, возможно, потеряв данные и запортив работу пользователя. вообще, неважно, даже если у программы нет пользователя и она работает в сервисном режиме - то тогда проблема становится ещё более актуальна: при неожиданном сбое не упасть, записать инфу в лог и продолжить работу.

Под особой дружественностью имелось ввиду то, что в исключении можно передать дополнительную диагностическую информацию "вверх по коду", и при его получении программа может ее сообщить (сохранить в лог).
Скажу больше. :) Я большой противник таких проверок в нижних сервисных участках кода, к которым по моему мнению относиться оператор []. Такие проверки должны выполняться выше.
Предположим у нас есть коллекция и метод, который выполняет действия с диапазонами из этой коллекции. Я могу один раз проверить диапазон на валидность и далее спокойно использовать оператор [] для получения элементов. А если при каждом вызове оператора [] он будет проверять (уже проверенный) индекс, то.... скорее всего я не буду его использовать. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.4.2010, 11:31
Сообщение #10


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Другими словами Assert внутри оператора [], это вполне хорошо?
Например в сравнении с его отсутствием (программа тоже может упасть, но не сразу)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 22.4.2010, 12:10
Сообщение #11


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Я так понял что BRE предлагает использовать проверку значения индекса на вхождение в range коллекции не в операторе [], а где-то выше по уровню реализации.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.4.2010, 12:18
Сообщение #12


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


это-то понятно. Я для случая, если всё таки прозивал, то внутри оператора делать ли assert или нет.
assert гарантировано завалит приложение, выдав на консоль номер строки и файла, в котором он сработал.
А вот без него работа программы может продолжится (случалось)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 22.4.2010, 12:26
Сообщение #13


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


А как ты можешь прозевать фиктивный индекс?
Всмысле, если ты организуешь механизм проверки индекса в отрезке коллекции, то я думаю что пропустить его как-то..не реально?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 22.4.2010, 12:29
Сообщение #14


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Litkevich Yuriy @ 22.4.2010, 13:18) *
это-то понятно. Я для случая, если всё таки прозивал, то внутри оператора делать ли assert или нет.
assert гарантировано завалит приложение, выдав на консоль номер строки и файла, в котором он сработал.
А вот без него работа программы может продолжится (случалось)

assert лучший друг программиста. :)
IMHO, использовать обязательно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.4.2010, 13:20
Сообщение #15


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


имхо ассерты только для дебага. ну, в крайнем случае, можно их оставить на время приёмо-отладочных работ. но не в рабочей версии. а так, честно ловить экспшны и выдавать информацию для пользователя (ну либо сразу формировать технический отчёт, который пользователь может выслать программисту).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.4.2010, 13:34
Сообщение #16


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Iron Bug @ 22.4.2010, 17:20) *
а так, честно ловить экспшны
а к стати какое-то конкретное исключение возникает при обращении в не разрешённую область памяти?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 22.4.2010, 13:45
Сообщение #17


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


memory access violation ?:)

вот тут обсуждалось

Сообщение отредактировал Andrewshkovskii - 22.4.2010, 13:46
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.4.2010, 13:47
Сообщение #18


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Andrewshkovskii @ 22.4.2010, 17:45) *
memory access violation ?
похоже что так
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 23.4.2010, 8:46
Сообщение #19


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


В Винде возникает системное исключение STATUS_ACCESS_VIOLATION как правильно указал Andrewshkovskii.
Некоторые компиляторы в некоторых режимах умеют переводить системные исключения винды в исключения С++.
Например MSVC с нужной опцией или багланд в режиме совместимости с делфой.

В унихе возникает системный сигнал SIGSEGV.

Читай, например, в википедии. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 23.4.2010, 11:24
Сообщение #20


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Цитата(Iron Bug @ 22.4.2010, 13:20) *
имхо ассерты только для дебага. ну, в крайнем случае, можно их оставить на время приёмо-отладочных работ. но не в рабочей версии.

Хм, так вроде бы assert() и имеет смысл только в дебажной версии; в release версии он раскрывается в "ничто" и исключается компилятором. Нет? А заказчику всяко поставляется Release сборка, но не Debug.
Что же до "приёмо-отладочных работ", то (имхо) отладка ПО и приемо-сдаточные испытания (ПСИ) - это совершенно различные этапы работ, и второй может начинаться только после полного окончания первого.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 23.4.2010, 11:41
Сообщение #21


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Влад @ 23.4.2010, 15:24) *
в release версии он раскрывается в "ничто" и исключается компилятором. Нет?
Q_ASSERT в релизной работает. если я программу из командной строки запускаю (в виндовозе), то при падении вижу сообщение с номером строки исходника и текстом условия, которое проверялось
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 23.4.2010, 11:43
Сообщение #22


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Litkevich Yuriy @ 23.4.2010, 12:41) *
Цитата(Влад @ 23.4.2010, 15:24) *
в release версии он раскрывается в "ничто" и исключается компилятором. Нет?
Q_ASSERT в релизной работает. если я программу из командной строки запускаю (в виндовозе), то при падении вижу сообщение с номером строки исходника и текстом условия, которое проверялось

Собирай релиз с QT_NO_DEBUG, не будет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 23.4.2010, 11:44
Сообщение #23


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Litkevich Yuriy @ 23.4.2010, 12:41) *
Цитата(Влад @ 23.4.2010, 15:24) *
в release версии он раскрывается в "ничто" и исключается компилятором. Нет?
Q_ASSERT в релизной работает.

Вы о разных assertax говорите. ;)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 23.4.2010, 11:45
Сообщение #24


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(BRE @ 23.4.2010, 15:43) *
Собирай релиз с QT_NO_DEBUG, не будет.
лучше пусть будет :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V   1 2 3 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 16.4.2025, 3:08