Работа со множествами, FPC, Будьте аккуратнее :) |
Работа со множествами, FPC, Будьте аккуратнее :) |
volvo |
5.11.2010 22:51
Сообщение
#1
|
Гость |
Привет всем.
Сегодня наткнулся на непонятное (с точки зрения Паскаля) поведение FPC. Вот такой простейший код, совершенно корректно отрабатывающий в Турбо Паскале: type Попробуйте без его компиляции и запуска определить, что будет выведено на печать. А потом запустите на выполнение... Так что осторожнее с множествами... |
TarasBer |
5.11.2010 23:02
Сообщение
#2
|
Злостный любитель Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: 62 |
Должно быть 7 же, а в ФПЦ чё за прикол происходит?
-------------------- |
Archon |
5.11.2010 23:17
Сообщение
#3
|
Профи Группа: Пользователи Сообщений: 618 Пол: Мужской Репутация: 24 |
FreePascal 2.4.0. Предсказуемо, 7.
-------------------- Close the World...txeN eht nepO
|
volvo |
5.11.2010 23:20
Сообщение
#4
|
Гость |
Ну вот, и я думал, что 7...
Однако, на самом деле происходит очень неприятная штука (FPC 2.4.0, Debug/Normal mode, любой из режимов совместимости TP/ObjFPC/Delphi/FPC):
15 строка - это if s[i] in myset then inc(count); Как только очередной символ строки не входит во множество допустимых значений для myset - программа завершается аварийно при попытке проверить In. В багтрекере есть одна ошибка, связанная с множествами (она уже исправлена, в 2.5.1). Но этой нет. Вот я и думаю, это ж баг? Так быть не должно - не присутствует значение во множестве, значит надо вернуть False и все. |
Lapp |
6.11.2010 2:45
Сообщение
#5
|
Уникум Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
Вот я и думаю, это ж баг? Так быть не должно - не присутствует значение во множестве, значит надо вернуть False и все. Другими словами, ты полагаешь, что тут должно работать автоматическое приведение типов? Но как?Мне такое поведение представяется логичным.. То есть сравнение (выяснение принадлежности) происходит только для элементов множества. Не элемент - выяснение невозможно. Сейчас пытался сделать нечто подобное для чисел и без множеств.. Не вышло )). Числовые типы приводятся, похоже, всегда. Например: {$R+} - это отрабатывает на ура без всяких ошибок.. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
volvo |
6.11.2010 2:59
Сообщение
#6
|
Гость |
Цитата Не элемент - выяснение невозможно. , и надо выбрасывать критическую ошибку, да? В топку такое поведение. У меня не строка может состоять из символов 'a'..'z', а посторонняя переменная. И если символ из строки в ней не присутствует или не может присутствовать - то In должен вернуть False.Заметь, подобное поведение было как минимум до версии 2.0.0 (на двойке не помню, на 1.0.10 проверил только что - работает), обратная совместимость где? Да. И еще одно - что мне совершенно непонятно. Откомпилируем программу в Options -> Mode = Release, все прекрасно работает и в 2.4.0. То есть, все-таки баг в отладочных режимах. |
Lapp |
6.11.2010 3:04
Сообщение
#7
|
Уникум Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
И еще одно - что мне совершенно непонятно. Откомпилируем программу в Options -> Mode = Release, все прекрасно работает и в 2.4.0. То есть, все-таки баг в отладочных режимах. Гм. А разве в моде Release включен Range Checking?.. Володь, я в целом согласен, что фича ненужная и бесполезная. Я не могу привести примера для себя, где оно бы помогло. Но все же логику тут отрицать пока не могу. Я еще подумаю над этим.. Добавлено через 4 мин. , и надо выбрасывать критическую ошибку, да? Это обычный RangeCheck.. Выключи/включи его для этого куска кода - и проблема решена..-------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Lapp |
6.11.2010 8:26
Сообщение
#8
|
Уникум Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
Я еще подумаю над этим.. Я подумал, как и обещал. И по-прежнему считаю, что это совершенно правильное поведение компилятора строго типизированного языка (каковым является объектный Паскаль в поздних реализациях). Справедливости ради, скажу, что я так и думал, что именно это произойдет еще при первом просмотре кода. Я понимаю, что это не довод, конечно )).В твоем примере происходит обработка ВСЕХ входящих символов. Значит, конструкция для обработки должна принимать их ВСЕ. То, что в число "хороших" символов могут входить только буквы, еще не значит, что ты можешь ими ограничиться при обработке. Поэтому введение типа tset в этом коде не есть правильное действие. Если в твоем потоке символов предполагаются буквы и пробелы, а также цифры, но (допустим) никак не управляющие символы, то организуй соответствующее множество, и RCE (в процессе отладки, разумеется) будет означать, что пролез какой-нить ctrl-c, что есть признак ошики в коде и требует реакции программера. Так что, тут нет никакого бага, мне кажется. IMHO, ессно. Но довольно твердое . -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Archon |
6.11.2010 10:53
Сообщение
#9
|
Профи Группа: Пользователи Сообщений: 618 Пол: Мужской Репутация: 24 |
Delphi не ругается ни при выключенном RangeCheck, ни при включенном. При операциях с числами аргументы приводятся к большему диапазону, так-что я не вижу смысла в случае с множествами поступать иначе.
-------------------- Close the World...txeN eht nepO
|
Client |
6.11.2010 11:25
Сообщение
#10
|
Профи Группа: Пользователи Сообщений: 865 Пол: Мужской Реальное имя: Вячеслав Репутация: 20 |
ошибка всегда, если Range Checking включен, во всех 3 режимах.
и я считаю это злостным багом Сообщение отредактировано: Client - 6.11.2010 11:25 Эскизы прикрепленных изображений |
Lapp |
7.11.2010 5:31
Сообщение
#11
|
Уникум Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
При операциях с числами аргументы приводятся к большему диапазону, так-что я не вижу смысла в случае с множествами поступать иначе. То, что ты его не видишь, не значит, что его нет )). Я уже привел ситуацию, когда такое поведение может быть полезным. Что касается больший/меньший диапазон - это неправильное проектирование числовых свойств на множества. Мне это тоже сначала пришло в голову, потом я покрутил в мозгах и понял, что это совсем разные вещи. В числах диапазон - это, как правило, ограничение, наложенное вычислительными возможностями. А тут ты можешь задатьtak = set of 'a'..'k'; - и причиной для этого может быть именно отслеживание диапазона средствами компилятора на этапе отладки. Всякое "приведение, исходя из здравого смысла" тут неуместно. Арчон, ты в ладах с граматиками и т.п. stuff'ом, ты должен это понять (или строго доказать мне обратное)). Молчание volvo я склонен воспринимать как согласие со мной (если, конечно, он не супер занят на другом фронте)). Зная его нелюбовь признавать свои ляпы (очень редкие, правда), я полагаю, что он просто отмалчивается.. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
volvo |
7.11.2010 14:20
Сообщение
#12
|
Гость |
Я не отмалчиваюсь, я просто сейчас сидел и разбирался с ассемблерными листингами разных тестов работы со множествами. Смотри, что получается...
Берем кусок кода №1: // переменные описаны так:Что имеем на выходе? Вот что: # [18] if arr[ i ] in bset then inc(count); typeНа выходе:
Если так все-таки было задумано, то чего бы не сделать то же самое действие для целочисленных базовых типов - непонятно. Для перечислимых тоже есть такая проверка: typeточно так же, как и при работе с Char-ами вылетает при отладке. Неоднозначность какая-то получается. Учитывая то, что есть Generic-и - это ОЧЕНЬ нехорошая неоднозначность. |
Lapp |
8.11.2010 4:12
Сообщение
#13
|
Уникум Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
Если так все-таки было задумано, то чего бы не сделать то же самое действие для целочисленных базовых типов - непонятно. Для перечислимых тоже есть такая проверка: Да, с этим я не могу не согласиться. Явная неоднозначность. И неоднозначность плохая, да. В такой ситуации ответ может дать только тот, кто делал.. Володь, ты еще не запостил этот вопрос на форум FP?<...> Неоднозначность какая-то получается. Учитывая то, что есть Generic-и - это ОЧЕНЬ нехорошая неоднозначность. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
volvo |
8.11.2010 13:28
Сообщение
#14
|
Гость |
Нет еще... Сегодня вечером запощу.
|
Текстовая версия | 28.09.2024 4:05 |