вторник, 10 января 2017 г.

#1331. Забавный баг 64-битного компилятора

const
 csRusSmallI = AnsiChar('и');
 csRusBigI = AnsiChar('И');
 csSetRusI = [csRusSmallI, csRusBigI];
begin
 Assert(#0 in csSetRusI);
 //- проверка проходит, что НЕ правильно
end.
const
 csRusSmallI = AnsiChar('и');
 csRusBigI = AnsiChar('И');
 csSetRusI : set of AnsiChar = [csRusSmallI, csRusBigI];
begin
 Assert(#0 in csSetRusI);
 //- проверка НЕ проходит, что ПРАВИЛЬНО
end.

Delphi XE4

"Понятное дело", что есть CharInSet и CharInArray, но при портировании старого кода - малость раздражает.

Да. В 32-х битах - это не повторяется. На всякий случай повторил.

И "на самом деле" в первом примере значение csSetRusI равно ['и', 'И', #0, #2, #3]. Т.е. там какой-то "мусор". Завтра погляжу как это выглядит в ассемблере.

5 комментариев:

  1. Исправили видать уже. Нет бага в Не Delphi Berlin 10.1 Pro. Ассемблерного кода тоже нет (это ж константы!), даже в отладочном профиле компилятор предвычисляет всё на этапе компиляции.

    ОтветитьУдалить
    Ответы
    1. s/в Не Delphi/в Delphi/

      Удалить
    2. Ну видимо исправили.

      Ну так константы в коде можно же посмотреть. Либо это битовая маска, либо массив.

      Удалить
    3. Нет, нельзя. :) Там код сразу сжимается в raise EAssertionFailed.Create(<...>); потому что компилятор уже просчитал, что никаких других вариантов быть не может.

      Удалить
    4. Не ну понятно, что в ассемблере надо смотреть нерафинированный пример. Например со временной переменной. Чтобы компилятору было нечего оптимизировать.

      Удалить