Помилка integer overflow

помилка Integer overflow

Добрий день, уважемие майстра! У мене дурне питання, але тим не менше я не знаю на нього відповіді:
є такі змінні:

# XA0; X: DWORD;
A, B: DWORD;
і такий код:

включив Overflow checking - почав показувати помилку, причому в тому випадку, якщо B> A, тобто в дужках негативне число. X робити integer "ом небажано, там потім шматок на Асмі, він там використовується як ціле позитивне. У чому причина, я спеціально ABS поставив і не допомагає. Так, ще я спробував замість змінних написати значення, типу:

і все нормально! Чому так?

при включеній опції перевірки переповнення:

компілятор вважає, що при A, B: DWORD обчислене значення A-B так нехай має чин явний тип DWORD, в діапазон представлення значень якого отіц.значенія не входять, про що в ран-тайм і повідомляється винятком по integer overflow

компілятор взагалі генерує код виклику ф-ції Abs () і операції ц / ч множення, тому що все вираз можна обчислити на етапі компіляції, отримати свідомо однозначний результат = 10 і привласнити його змінної X, що ні порушить жодних винятків, благо результ.чісло 10 свідомо входить в діапазон представлення типу DWORD, тому код перевірки на переповнення компілятор навіть не генерує

читати як "взагалі НЕ генерує"


> X робити integer "ом небажано, там потім шматок на Асмі,
> Він там використовується як ціле позитивне

ніяких обмежень немає. використовуй в АСМ-блоці змінну Х як хочеш - хоч як знакова хоч як беззнаковое.

в дан.случае абсолютно індиферентно, який тип - integer або dword - має змінна Х, яка використовується в asm-блоці, важливо що розмір змінної в пам'яті і в тому і в іншому випадку буде однаковий

Хм. Зробив все таки заради експерименту

історія та ж, а ось після такої зміни:

помилка зникла. Вообщем проблема вирішена, але як - я не зрозумів.

Abs має сенсу для dword

і це теж зрозуміло


> Вообщем проблема вирішена, але як - я не зрозумів

дивно ти підходиш до вирішення проблеми - методом "наукового тику".

працюєш явно виразами, які беруть в ран-тайм в т.ч. і отріц.значенія (а інакше навіщо блазень тоді Abs, питається?), а змінні повідомляєш як беззнакові цілі.

та й з опцією overflow checking - теж ситуація сумнівна, бо в АСМ-блоці, де ти вільний творити з будь-якої змінної будь-якого типу все що завгодно, компілятор безсилий відстежувати твої логічні помилки

# XA0; X: byte;
# XA0; A: WORD;
# XA0; B: DWORD;

помилок немає! а якщо без Abs () то Range check error.
# XA0; (в момент налагодження A = 7; B = 8;)

# XA0; X: byte;
# XA0; A: WORD;
# XA0; B: DWORD;

помилок немає! а якщо без Abs () то Range check error.
# XA0; (в момент налагодження A = 7; B = 8;)
Справа в розрядності змінних чтоли? (16 bit, 32 bit)?


> Справа в розрядності змінних чтоли? (16 bit, 32 bit)?

в разі A-B компілятор вважає результуючим типом значення виразу тип dword, інакше - integer

ти начебто з АСМ-му знаком, якщо блоки на ньому використовуєш.
не так вже й важко подивитися в режимі налагодження, який маш.код компілятор генерує в тому чи іншому випадку.

X: = (Max (A, B) - Min (A, B)) * 2

і всіх делов). і ніяких переповнень).
різниця між макс. і хв. значеннями завжди буде> = 0


> # XA0; A - це ширина картинки в байтах розрахункова (к-ть точок
> Помножити на кількість бай на точку),
> # XA0; B - це ширина в байтах справжня, з вирівнюванням (bmp-файли
> # XA0; повинні ж бути "word aligned");
> # XA0; X - це величина "добавки", тобто скільки байт потрібно додати
> В кінець кожного рядка, щоб вирівняти за словами, вона не
> Може бути менше нуля теоретично

З цього випливає, що A, B і X можна описати як Integer і використовувати X: = Abs (A-B) * 2; як в питанні. Ну а якщо принципово вони повинні бути DWORD, то можна використовувати явне приведення типів X: = Abs (Integer (A) -B) * 2;
Подивившись на код, згенерований компілятором, буде видно, що, можливо, буде потрібно ще десь застосувати явне приведення типів.

Пам'ять: 0.76 MB
Час: 0.064 c

Схожі статті