21

Re: Переповнення char'ів

adziri написав:

Ні, не всюди, стандарт говорить, що діапазон char має бути,
як мінімум [-128,+127] але це implementation-defined, як і
те, що plain char може бути, як signed, так і unsigned.
В вашому випадку в циклі ви маєте UB, через переповнення
знакових.

І з неврахуванням цього пов'язаний один веселий баг, коли PCAD-200x (не пам'ятаю вже, у якому пофіксили) у кодуванні CP-1251 давав на схемах набрати літеру 'я', але потім не міг відкрити цей файл (збережений як PCAD-ASCII).
Десь воно char неявно приводило до int, з 'я' (0xFF) отримувало -1 і радісно порівнювало його з EOF.
Добрі люди місце знайшли і патчик зробили :D

Подякували: wander, leofun012

22 Востаннє редагувалося wander (06.05.2019 09:58:16)

Re: Переповнення char'ів

ReAl написав:

Десь воно char неявно приводило до int, з 'я' (0xFF) отримувало -1 і радісно порівнювало його з EOF.

Гм, так, ймовірно там відбувалося так зване (чи званий? =.=)
Integral promotion, де наш char успішно розширювався до int,
а потім відбувався, якийсь, наприклад, Integral conversion, який
і присвоював назад вже -1, доречі як не дивно це не мало спричиняти UB.
Ох вже ці підводні камені :D

23

Re: Переповнення char'ів

adziri написав:

доречі як не дивно це не мало спричиняти UB.

Не знаю, що вони там накрутили, але якщо вони десь наробили своїх обгорток і, наприклад, десь зробили дурницю на кшталт

    char ch = fgetc(fp); /* Ось вам і UB, звуження типу */

і лише потім порівняли з EOF, то цілком могли отримати таку багу.
Ну а патч тоді мав складатися з заміни MOVSX (Sign eXtension) на MOVZX (Zero eXtension) чи чогось подібного.

24 Востаннє редагувалося wander (06.05.2019 21:58:00)

Re: Переповнення char'ів

ReAl написав:
adziri написав:

доречі як не дивно це не мало спричиняти UB.

Не знаю, що вони там накрутили, але якщо вони десь наробили своїх обгорток і, наприклад, десь зробили дурницю на кшталт

Точно вже не пам'ятаю як було раніше, але в С++11/17 ми мали
таку можна сказати well-defined поведінку, яка тим не менш є
implementation-defined:

conv.integral написав:
  • If the destination type is signed, the value is unchanged if it can be represented in the destination type;

  • otherwise, the value is implementation-defined.

Це ми маємо при оберненому звуженні при integral conversion.
А от в С++20 вже поведінка інша, раніше пункт про 2^N
був тільки для беззнакових, тепер воно для обох версій, але,
не варто забувати, що це чернетка.

ReAl написав:
    char ch = fgetc(fp); /* Ось вам і UB, звуження типу */

і лише потім порівняли з EOF, то цілком могли отримати таку багу.

Ну так, приблизно про це я і писав, лиш це не UB :)
Я ж за що і кажу, випадково вистрілили самі ж собі в коліно ))

25

Re: Переповнення char'ів

adziri написав:

А от в С++20 вже поведінка інша, раніше пункт про 2^N
був тільки для беззнакових, тепер воно для обох версій, але,
не варто забувати, що це чернетка.

О, ага, вот воно що..
Зайшов винуватця http://www.open-std.org/jtc1/sc22/wg21/ … 236r1.html
Виявляється з С++20 тепер переповнення знакових буде well-defined?