![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
Litkevich Yuriy |
![]()
Сообщение
#1
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
у меня возник вопрос - "а хорошо ли программе падать?"
Есть перегруженный оператор [], в него передаётся индекс, и внутри оператора сделан assert на случай выхода индекса за границы разрешённого диаппазона. Вроде так многие делают. Но правильно ли это? Может правильнее поступать как-то иначе? |
|
|
DIMEDROLL |
![]()
Сообщение
#2
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 165 Регистрация: 28.9.2008 Из: Киев Пользователь №: 304 Спасибо сказали: 23 раз(а) Репутация: ![]() ![]() ![]() |
Может правильнее поступать как-то иначе? зависит от ситуации, есть три варианта: - индекс как то зависит пользователя программы: от введенных пользователем данных, открытых им файлов и т.д., Тогда нужно делать проверку и в случае неправильного индекса выводить ошибку или вызывать исключение - индекс зависит от программиста, тоесть получается в результате какого то алгоритма или просто жестко забит. Тогда просто ассерт и в дебаге фиксить. - от пользователя и программиста, тогда лучше и ассерт и обработку ошибки делать Добавлено: ИМХО ассерт - лучший друг программиста, ассертить можно все на что опираешься(напрмер, "эта переменная не должна быть ниже нуля"): входящие данные, выходящие данные, указатели, результаты connect, а уж тем более индексацию массивов... Зачастую, с помощью ассертов я находил такие баги что с дебаггером искал бы не один час. И бывало что с дебаггером сидел пол для, что бы обнаружить запись на 1 значение дальше конца массива. Но не надо забывать о чистоте кода, если все и везде ассертить выйдет каша в коде, Сообщение отредактировал DIMEDROLL - 21.4.2010, 12:15 |
|
|
Litkevich Yuriy |
![]()
Сообщение
#3
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
вообще я всюду стараюсь использовать не просто int, а собственный тип данных, например так:
это позволяет при программировании защитится от случайных входных значений. Но с индексами так не получается работать. И к сожалению в С\С++ нет типа диаппазонаЯ вроде пытаюсь себя дисциплинировать такими вещами: но к сожалению тоже не всегда применяю, часто потому-что не могу быстро решить, что делать.
|
|
|
BRE |
![]()
Сообщение
#4
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
IMHO, в операторе [] выход за пределы контейнера это по любому ошибка в коде программы. Ввод пользователя должен быть проверен еще до входа в этот метод. Такие ошибки должны отслеживаться еще на этапе отладки. Т.е. assert вполне удовлетворяет этим условиям, к тому же в релизе мы избавляемся от кода проверки.
Хотя, для особо дружественных программ можно использовать исключение, и при его возникновении сообщать пользователю, что произошла внутренняя ошибка # ... и ему нужно связаться с разработчиками. |
|
|
Litkevich Yuriy |
![]()
Сообщение
#5
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
в случае источником индекса со стороны пользователя, сравнительно просто. А в случае если источник, информация пришедшая с коммуникационного ресурса, уже не так просто, разумеется касяк где-то в коде, в алгоритме. И всплывает не однозначно, может месяцами себя ни как не проявлять при непрерывной работе ПО.
И Ассерт, здесь не информативен, т.к. в релизе кроме как в консоль он ничего не пишет, а её никто не видит. Просто "Бац и программа вылетела" |
|
|
BRE |
![]()
Сообщение
#6
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Все внешние данные, не важно откуда они приходят, должны быть проверенны еще до оператора []. По любому.
![]() assert в этом операторе, только для программиста и говорит о том, что он где-то выше забыл проверить индекс. |
|
|
Tonal |
![]()
Сообщение
#7
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 452 Регистрация: 6.12.2007 Из: Новосибирск Пользователь №: 34 Спасибо сказали: 69 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Iron Bug |
![]()
Сообщение
#8
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
IMHO, в операторе [] выход за пределы контейнера это по любому ошибка в коде программы. Ввод пользователя должен быть проверен еще до входа в этот метод. Такие ошибки должны отслеживаться еще на этапе отладки. Т.е. assert вполне удовлетворяет этим условиям, к тому же в релизе мы избавляемся от кода проверки. Хотя, для особо дружественных программ можно использовать исключение, и при его возникновении сообщать пользователю, что произошла внутренняя ошибка # ... и ему нужно связаться с разработчиками. вот тоже так думаю. и "особая дружественность" тут ни при чём. любой эксепшн должен обрабатываться и не приводить к обрушению программы. это ненормальное программирование, если программист позволяет своей программе просто так взять и рухнуть, возможно, потеряв данные и запортив работу пользователя. вообще, неважно, даже если у программы нет пользователя и она работает в сервисном режиме - то тогда проблема становится ещё более актуальна: при неожиданном сбое не упасть, записать инфу в лог и продолжить работу. да, тоже вариант: использование более надёжных объектов для хранения данных. у буста есть структуры для хранения произвольных данных, для обозначения "не числа" (т.е. переменная может содержать информацию, что её значение не валидно) и т.п. так что осваивайте и используйте на здоровье. Сообщение отредактировал Iron Bug - 22.4.2010, 8:32 |
|
|
BRE |
![]()
Сообщение
#9
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
вот тоже так думаю. и "особая дружественность" тут ни при чём. любой эксепшн должен обрабатываться и не приводить к обрушению программы. это ненормальное программирование, если программист позволяет своей программе просто так взять и рухнуть, возможно, потеряв данные и запортив работу пользователя. вообще, неважно, даже если у программы нет пользователя и она работает в сервисном режиме - то тогда проблема становится ещё более актуальна: при неожиданном сбое не упасть, записать инфу в лог и продолжить работу. Под особой дружественностью имелось ввиду то, что в исключении можно передать дополнительную диагностическую информацию "вверх по коду", и при его получении программа может ее сообщить (сохранить в лог). Скажу больше. ![]() Предположим у нас есть коллекция и метод, который выполняет действия с диапазонами из этой коллекции. Я могу один раз проверить диапазон на валидность и далее спокойно использовать оператор [] для получения элементов. А если при каждом вызове оператора [] он будет проверять (уже проверенный) индекс, то.... скорее всего я не буду его использовать. ![]() |
|
|
Litkevich Yuriy |
![]()
Сообщение
#10
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
Другими словами Assert внутри оператора [], это вполне хорошо?
Например в сравнении с его отсутствием (программа тоже может упасть, но не сразу) |
|
|
![]() ![]() ![]() |
![]() |
Текстовая версия | Сейчас: 17.2.2025, 0:05 |