IPB
ЛогинПароль:

> 

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

> Работа со множествами, FPC, Будьте аккуратнее :)
сообщение
Сообщение #1


Гость






Привет всем.

Сегодня наткнулся на непонятное (с точки зрения Паскаля) поведение FPC. Вот такой простейший код, совершенно корректно отрабатывающий в Турбо Паскале:

type
tset = set of 'a' .. 'z';
const
myset: tset = ['a' .. 'z'];
s: string = 'the test';
count: integer = 0;
var
i: integer;

begin
for i := 1 to length(s) do
begin
if s[ i ] in myset then inc(count);
end;
writeln(count);
end.

Попробуйте без его компиляции и запуска определить, что будет выведено на печать. А потом запустите на выполнение... smile.gif

Так что осторожнее с множествами...
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


Гость






Я не отмалчиваюсь, я просто сейчас сидел и разбирался с ассемблерными листингами разных тестов работы со множествами. smile.gif Смотри, что получается...

Берем кусок кода №1:
// переменные описаны так:
type
byteset = set of 128 .. 255;
const
bset: byteset = [128 .. 255];
arr: array[1 .. 5] of byte = (1, 128, 129, 130, 131);

//
for i := 1 to 5 do
if arr[ i ] in bset then inc(count);
writeln(count);

Что имеем на выходе? Вот что:
# [18] if arr[ i ] in bset then inc(count);
movl U_P$PROGRAM_I,%eax
subl $1,%eax
cmpl $4,%eax
jbe .Lj8
call FPC_RANGEERROR
.Lj8:
movl U_P$PROGRAM_I,%edx
movl %edx,%eax
subl $1,%eax
cmpl $4,%eax
jbe .Lj9
call FPC_RANGEERROR
.Lj9:
movzbl TC_P$PROGRAM_ARR-1(,%edx,1),%eax
btl %eax,TC_P$PROGRAM_BSET

jc .Lj6
jmp .Lj7
.Lj6:
movl TC_P$PROGRAM_COUNT,%eax
addl $1,%eax
jno .Lj12
call FPC_OVERFLOW
.Lj12:
movl %eax,TC_P$PROGRAM_COUNT
.Lj7:
cmpl $5,U_P$PROGRAM_I
jl .Lj5
.stabn 68,0,19,.Ll4 - _main
.Ll4:
# [19] writeln(count);
. Обратил внимание? Сразу запихиваем содержимое очередного элемента массива в EAX, и смотрим, есть ли оно в множестве. А теперь вышеприведенный мной код:
type
tset = set of 'a' .. 'z';
const
myset: tset = ['a' .. 'z'];
s: string = 'the test';

//
for i := 1 to length(s) do
if s[ i ] in myset then inc(count);
writeln(count);

На выходе:

# [24] if s[ i ] in myset then inc(count);
movl U_P$PROGRAM_I,%edx
cmpl $255,%edx
jbe .Lj30
call FPC_RANGEERROR
.Lj30:
movzbl U_P$PROGRAM_I,%ecx
movzbl TC_P$PROGRAM_S(,%ecx,1),%edx
subl $97,%edx
cmpl $25,%edx
jbe .Lj31
call FPC_RANGEERROR

.Lj31:
movzbl TC_P$PROGRAM_S(,%ecx,1),%edx
btl %edx,TC_P$PROGRAM_MYSET

jc .Lj28
jmp .Lj29
.Lj28:
movl TC_P$PROGRAM_COUNT,%edx
addl $1,%edx
jno .Lj34
call FPC_OVERFLOW
.Lj34:
movl %edx,TC_P$PROGRAM_COUNT
.Lj29:
cmpl U_P$PROGRAM_I,%eax
jg .Lj27
.Lj26:
.stabn 68,0,26,.Ll8 - _main
.Ll8:
# [26] writeln(count);
То есть, сначала из выдирается очередной символ, от него отнимается 97 (ну, это понятно - приводим к началу отсчета, 'a' считается нулевым элементом множества - значит ото всего будем отнимать 97, начинался бы интервал при описании tset с 'b' - отнимали бы 98), потом проверяем результат на попадание в допустимый интервал (26 символов, начиная с 0 - если значение больше 25, то RCE). А потом опять выдираем значение из строки и его уже проверяем на наличие во множестве...

blink.gif Если так все-таки было задумано, то чего бы не сделать то же самое действие для целочисленных базовых типов - непонятно. Для перечислимых тоже есть такая проверка:
type
t = (_1, _2, _3, _4);
st = set of _2 .. _4;

const
ssv: st = [_2 .. _4];
one: t = _1;
begin
if one in ssv then
writeln('wrong');
end.
точно так же, как и при работе с Char-ами вылетает при отладке.

Неоднозначность какая-то получается. Учитывая то, что есть Generic-и - это ОЧЕНЬ нехорошая неоднозначность.
 К началу страницы 
+ Ответить 

Сообщений в этой теме
volvo   Работа со множествами, FPC   6.11.2010 2:51
TarasBer   Должно быть 7 же, а в ФПЦ чё за прикол происходит?   6.11.2010 3:02
Archon   FreePascal 2.4.0. Предсказуемо, 7.   6.11.2010 3:17
volvo   Ну вот, и я думал, что 7... Однако, на самом дел…   6.11.2010 3:20
Lapp   Вот я и думаю, это ж баг? Так быть не должно - не …   6.11.2010 6:45
volvo   , и надо выбрасывать критическую ошибку, да? В топ…   6.11.2010 6:59
Lapp   И еще одно - что мне совершенно непонятно. Откомпи…   6.11.2010 7:04
Lapp   Я еще подумаю над этим..Я подумал, как и обещал. …   6.11.2010 12:26
Archon   Delphi не ругается ни при выключенном RangeCheck, …   6.11.2010 14:53
Lapp   При операциях с числами аргументы приводятся к бол…   7.11.2010 9:31
Client   ошибка всегда, если Range Checking включен, во все…   6.11.2010 15:25
volvo   Я не отмалчиваюсь, я просто сейчас сидел и разбира…   7.11.2010 18:20
Lapp   Если так все-таки было задумано, то чего бы не сде…   8.11.2010 8:12
volvo   Нет еще... Сегодня вечером запощу.   8.11.2010 17:28


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

 





- Текстовая версия 20.04.2024 8:42
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name