Автор Тема: Семантика SHORT(x) в Компонентном Паскале  (Прочитано 33472 раз)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #15 : Декабрь 22, 2012, 07:27:51 pm »
В любом случае, Вы не будете ведь всякие преобразования форматов размазывать по коду.
У меня вот Unsigned-преобразования собраны в отдельном модуле...
Да. Тоже вариант.

qp

  • Newbie
  • *
  • Сообщений: 28
    • Просмотр профиля
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #16 : Декабрь 22, 2012, 08:16:07 pm »
Предлагаю исправленный вариант процедуры WriteChar() из модуля TextModels в Блэкбоксе:
А зачем? Какой в этом смысл?
Пусть будет переполнение.
Как это зачем? Вот, решите вы прогнать свой проект со всеми включенными проверками, для очистки совести, так сказать  :). А он возьмёт, да и срубиться на этих строчках кода.

К тому же, если вы решите перейти на другой компилятор, то где гарантия, что в нём "SHORT просто отбросит старшие биты"? Это особенность конкретной реализации, на которую закладываться не стоит.
Простейший пример: BlackBox по-умолчанию не реагирует на переполнение, та же самая программе не будет работать с gpcp, т.к. .NET при переполнении выдаст исключение:-(

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #17 : Декабрь 23, 2012, 06:36:02 am »
В принципе, это цепляние к конкретной заоптимизированной реализации текстов.
То есть вы не признаёте, что во второй строчке кода сейчас есть ошибка?
В процедуру WriteByte() старший байт кода символа передаётся с проинвертированным старшим битом. Это с отключенными проверками.
Я бы не стал это называть "заоптимизированной реализацией".  ;)

Илья Ермаков

  • Sr. Member
  • ****
  • Сообщений: 493
    • Просмотр профиля
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #18 : Декабрь 23, 2012, 02:31:46 pm »
Под заоптмизированностью я имею в виду то, что они там используют запись напрямую в файл, минуя Stores.Writer.

А что они ошиблись именно так, как мы думаем... Тогда бы в обоих строчках было -128.

Короче говоря, вольно или невольно получили они своё кодирование символов :)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #19 : Декабрь 23, 2012, 02:38:04 pm »
Мой вариант:  :)
PROCEDURE Do*;
    VAR
        ch: CHAR;
        b1, b2: BYTE;
        i: INTEGER;
BEGIN
   
    FOR i := 0 TO 65535 DO
       
        ch := CHR(i);
       
        b1 := SHORT(SHORT(ASH(ASH(ORD(ch), 24), -24)));
        b2 := SHORT(SHORT(ASH(ASH(ORD(ch), 16), -24)));
         
        ASSERT(ch = CHR((ASH(b2 MOD 256, 8) + b1 MOD 256)));
   
    END;

END Do;

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #20 : Декабрь 23, 2012, 02:58:09 pm »
Мой вариант:  :)
Неплохой вариант. Но проверки придётся таки отключить.  ;)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #21 : Декабрь 23, 2012, 03:07:54 pm »
А что они ошиблись именно так, как мы думаем... Тогда бы в обоих строчках было -128.

Игорь хотел сказать, что они ошиблись в любом случае, независимо от того, что мы думаем  ;)
У них 2+2=5, и это косяк как ни крути.

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #22 : Декабрь 23, 2012, 03:10:04 pm »
Мой вариант:  :)
Неплохой вариант. Но проверки придётся таки отключить.  ;)
Почему?

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #23 : Декабрь 23, 2012, 03:20:34 pm »
Неплохой вариант. Но проверки придётся таки отключить.  ;)
Почему?
Ну, давайте рассмотрим вот эту строчку:
        b1 := SHORT(SHORT(ASH(ASH(ORD(ch), 24), -24)));
Арифметический сдвиг влево на 24 бита, а затем вправо на 24 бита никак не влияет на младший байт кода символа. А проблема именно в нём. Если у него старший бит равен "единице", то во время выполнения внешнего SHORT возникнет переполнение.

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #24 : Декабрь 23, 2012, 03:34:26 pm »
Фишка в том, что сдвиг арифметический, и следовательно тянет за собой знак:
x = 0000 0000 - 0000 0000 - 0000 0000 - 1000 0000 = 128 (будет переполнение, ибо не помещается в байт)
x = ASH(ASH(x, 24), -24)
x = 1111 1111 - 1111 1111 - 1111 1111 - 1000 0000 = -128 (нет переполнения)  ;)

ps Вы же сами упоминали что SHORT делает идентичное преобразование
« Последнее редактирование: Декабрь 23, 2012, 03:37:10 pm от ilovb »

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #25 : Декабрь 23, 2012, 03:42:27 pm »
Фишка в том, что сдвиг арифметический, и следовательно тянет за собой знак:
x = 0000 0000 - 0000 0000 - 0000 0000 - 1000 0000 = 128 (будет переполнение, ибо не помещается в байт)
x = ASH(ASH(x, 24), -24)
x = 1111 1111 - 1111 1111 - 1111 1111 - 1000 0000 = -128 (нет переполнения)  ;)

ps Вы же сами упоминали что SHORT делает идентичное преобразование
Как говорит Илья, век живи - век учись.  :)
Вы правы. Причём, ваш вариант даже лучше, чем мой. Потому что не требует никаких IF'ов.
(Я не учёл, что расширение знака влияет на значение младшего байта)

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #26 : Декабрь 23, 2012, 04:05:36 pm »
Если ASH это реально ASH, но я видел такую чехарду... - это транслировалось и в SAL/SAR и в SHL/SHR

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #27 : Декабрь 23, 2012, 04:09:05 pm »
Такое может быть только при кривом компиляторе. ASH всегда должен компилиться в SAL/SAR.

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #28 : Декабрь 23, 2012, 04:22:05 pm »
PROCEDURE Shift* (VAR x, y: DevCPL486.Item; subcl: BYTE);    (* ASH, LSH, ROT *)
        VAR L1, L2: DevCPL486.Label; c: DevCPL486.Item; opl, opr: INTEGER;
    BEGIN
        IF subcl = ash THEN opl := SHL; opr := SAR
        ELSIF subcl = lsh THEN opl := SHL; opr := SHR
        ELSE opl := ROL; opr := ROR
        END;
        IF y.mode = Con THEN
            IF y.offset > 0 THEN
                DevCPL486.GenShiftOp(opl, y, x)
            ELSIF y.offset < 0 THEN
                y.offset := -y.offset;
                DevCPL486.GenShiftOp(opr, y, x)
            END
        ELSE
            ASSERT(y.mode = Reg);
            Check(y, -31, 31);
            L1 := DevCPL486.NewLbl; L2 := DevCPL486.NewLbl;
            DevCPL486.MakeConst(c, 0, y.form); DevCPL486.GenComp(c, y);
            DevCPL486.GenJump(ccNS, L1, TRUE);
            DevCPL486.GenNeg(y, FALSE);
            DevCPL486.GenShiftOp(opr, y, x);
            DevCPL486.GenJump(ccAlways, L2, TRUE);
            DevCPL486.SetLabel(L1);
            DevCPL486.GenShiftOp(opl, y, x);
            DevCPL486.SetLabel(L2);
            Free(y)
        END;
        IF x.mode # Reg THEN Free(x) END
    END Shift;

ps SHL = SAL

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Семантика SHORT(x) в Компонентном Паскале
« Ответ #29 : Декабрь 23, 2012, 04:50:54 pm »
Цитировать
allchecks - добавить в исполняемый модуль код, выполняющий дополнительные проверки (переполнение и выход за диапазон значений для целых чисел).
Секреты компилятора

srcpos - Включает запись в объектник информации о соответствии позиции исходного кода смещению в машинном коде.