Remkomplekty.ru

IT Новости из мира ПК
3 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Integer overflow ошибка

Integer overflow ошибка

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

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

включил Overflow checking — начал показывать ошибку, причем в том случае, если B>A, т.е. в скобках отрицательное число. X делать integer»ом нежелательно, там потом кусок на асме, он там используется как целое положительное. В чем причина, я специально ABS поставил и не помогает. Да, еще я попробовал вместо переменных написать значения, типа:

и все нормально! Почему так?


Digitman © ( 2004-06-08 10:35 ) [1]

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

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

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


Digitman © ( 2004-06-08 10:37 ) [2]

читать как «вообще НЕ генерирует»


Digitman © ( 2004-06-08 10:42 ) [3]


> X делать integer»ом нежелательно, там потом кусок на асме,
> он там используется как целое положительное

никаких ограничений нет : используй в асм-блоке переменную Х как хочешь — хоть как знаковое хоть как беззнаковое .

в дан.случае абсолютно индифферентно, какой тип — integer или dword — имеет переменная Х, используемая в asm-блоке, важно что размер переменной в памяти и в том и в другом случае будет одинаков


ancara ( 2004-06-08 10:46 ) [4]

Хм. Сделал все таки ради эксперимента

история та же, а вот после такого изменения:

ошибка исчезла. Вообщем проблема решена, но как — я не понял.


Anatoly Podgoretsky © ( 2004-06-08 10:47 ) [5]

Abs бессмысленен для dword


pasha_golub © ( 2004-06-08 10:48 ) [6]

ancara (08.06.04 10:46) [4]
Проблема не решена, ИМХО, а завуалирована. Перечитайте посты Digitman © очень внимательно, иначе рискуете отгребсти по самые мама не горюй.


Digitman © ( 2004-06-08 10:52 ) [7]

и это тоже объяснимо


> Вообщем проблема решена, но как — я не понял

странно ты подходишь к решению проблемы — методом «научного тыка» ..

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

да и с опцией overflow checking — тоже ситуация сомнительная, ибо в асм-блоке, где ты волен творить с любой переменной любого типа все что угодно, компилятор бессилен отслеживать твои логические ошибки


ancara ( 2004-06-08 10:57 ) [8]

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

ошибок нет! а если без Abs() то Range check error.
(в момент отладки A=7; B=8;)


ancara ( 2004-06-08 10:58 ) [9]

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

ошибок нет! а если без Abs() то Range check error.
(в момент отладки A=7; B=8;)
Дело в разрядности переменных чтоли? (16 bit, 32 bit)?


ancara ( 2004-06-08 11:09 ) [10]


> Digitman © (08.06.04 10:52) [7]

Я поясню: overflow checking я включаю время от времени (иногда всегда включен) чтобы компилятор указал на разные «слабые места», привычка у меня такая, я не только для асма ее включил.
А насчет беззнаковых — прога ориентирована на графику,
A — это ширина картинки в байтах расчетная(кол-во точек умножить на кол-во бай на точку),
B — это ширина в байтах истинная, с выравниванием (bmp-файлы должны же быть «word aligned»);
X — это величина «добавки», т.е. сколько байт нужно добавить в конец каждой строки, чтобы выравнять по словам, она не может быть меньше нуля теоретически,( но в проге почему-то может и я буду это устранять. )
именно поэтому я выбрал изначально DWORD.


Digitman © ( 2004-06-08 11:15 ) [11]


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

в случае A-B компилятор считает результирующим типом значения выражения тип dword, иначе — integer

ты вроде бы с асм-ом знаком, коль блоки на нем используешь .
не так уж и трудно посмотреть в режиме отладки, какой маш.код компилятор генерирует в том или ином случае ..


ancara ( 2004-06-08 11:43 ) [12]


> не так уж и трудно посмотреть в режиме отладки, какой маш.код
> компилятор генерирует

Вы совершенно правы :), в регистре EAX вместо 00000001 получается FFFFFFFE, а потом это рассмартивается как BYTE — маразм!
Спасибо за ценные советы.


Digitman © ( 2004-06-08 11:53 ) [13]

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

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


evvcom © ( 2004-06-08 14:42 ) [14]


> A — это ширина картинки в байтах расчетная(кол-во точек
> умножить на кол-во бай на точку),
> B — это ширина в байтах истинная, с выравниванием (bmp-файлы
> должны же быть «word aligned»);
> X — это величина «добавки», т.е. сколько байт нужно добавить
> в конец каждой строки, чтобы выравнять по словам, она не
> может быть меньше нуля теоретически

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

Integer overflow ошибка

не надо фантазий.
в правой части выражения у вас 2 константы. числовые константы по умолчанию имеют тип int. результат любого выражения (промежуточные результаты вычислений) по умолчанию будет совпадать с int (если все составные части меньше или равны int) или с наибольшим «размером типа» входящих в выражение элементов — в вашем случае int. и лишь после всех вычислений результат преобразуется в тип, необходимый для левой части, т.е. для переменной long

естественно, при умножении int * int результат в int может не поместиться — о чем компилятор вам и говорит. хотите избавиться от проблемы — сделайте так, чтобы какой-то элемент в правой части имел тип long, например так:

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
удивительно, но при взгляде на многих сверху ничего не меняется.

Сборка печатных плат от $88 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Последний раз редактировалось smac Сб дек 13, 2008 15:37:22, всего редактировалось 1 раз.

15 апреля приглашаем на вебинар, который будет интересен разработчикам и инженерам-схемотехникам, интересующимся тенденциями рынка, новыми перспективными решениями для соединений «провод-провод», «провод-плата», «плата-плата». Для инженеров КИПиА и IT будут освещены уникальные решения Molex для «удлинения» интерфейсов HDMI, DisplayPort и USB даже в условиях сильного зашумления, а также семейство бесконтактных датчиков Contrinex. Помимо этого, будет уделено внимание дальнейшему развитию направления антенн, где Molex имеет ряд интересных и уникальных решений.

Читать еще:  Ворд не подчеркивает ошибки что делать

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
удивительно, но при взгляде на многих сверху ничего не меняется.

Компактные источники питания Mornsun изготавливаются как в виде миниатюрных открытых печатных плат (семейство LS с мощностью 1…15 Вт; семейство LO мощностью 3…65 Вт), устанавливаемых на основную плату устройства, так и в виде корпусированных модулей с повышенным уровнем защиты и надежности (семейства LD/LH мощностью 2…60 Вт).

Естественно можно, только вот речь шла не о сложении, а об умножении, а там одного флага переноса не достаточно

Я предполагаю.
Тогда попробуй, скомпилить код с фрагментом PORTC = PORTD/PORTB.
и посмотри какая весёлая хрень получается.

И вообще из темы не совсем понятно: «warning» — это разве ошибка!?

Последний раз редактировалось pirotehnick Сб дек 13, 2008 17:46:08, всего редактировалось 1 раз.

странные хедеры для винавр
там avr/io.h должно быть
у тебя какая версия?

писать надо unsigned long int и переменная должна быть внутри мейн (если она не глобальная)

pirotehnick, в вашем «смешном» примере нет ничего удивительного. вы невнимательно прочитали мое сообщение. повторю: в Си все значения сначала приводятся к типу int (если иное не сказано) или к типу наибольшего элемента, затем производятся вычисления, а затем результат приводится к типу переменной, куда он записывается.

теперь ваш пример PORTC = PORTD/PORTB.
все переменные имеют тип unsigned char. значит, сначала PORTD и PORTB будут приведены к типу int, причем самое смешное в том, что беззнаковый байт будет преобразован в знаковый int, затем будет произведено деление, а затем от результата будет отброшен старший байт, а младший будет выведен в PORTC. надеюсь, вам не надо объяснять, что 0xFF будет превращено таким образом в -1, ну, и потом после деления будет что-то невероятное, а его младший байт — и того удивительнее.

что касается удивления в вычислении констаны. да, компилятор подставит конкретное число. только это число получается с переполнением int — вот он и предупреждает, что хрень какая-то будет в итоге (типа как в вашем примере с портами).

warning — это не ошибка, а предупреждение. но в некоторых случах это хуже ошибки. предупреждение может означать, что программа будет работать, но как именно — неизвестно. и в данном случае смысл как раз такой.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
удивительно, но при взгляде на многих сверху ничего не меняется.

Почему unsigned integer overflow определяет поведение, а signed integer overflow-нет?

переполнение целого числа без знака хорошо определяется стандартами C и c++. Например,стандарт C99 ( §6.2.5/9 ) государств

вычисление с использованием неподписанных операндов никогда не может переполняться, потому что результатом, который не может быть представлен результирующим целочисленным типом без знака, является уменьшенное по модулю число, которое больше наибольшего значения, которое может быть представлен результирующим типом.

однако, как стандарты утверждают, что переполнение целого числа со знаком является неопределенным поведением. Опять же, из стандарта C99 ( §3.4.3/1 )

примером неопределенного поведения является поведение при переполнении целого числа

есть ли исторический или (еще лучше!) техническая причина этого несоответствия?

5 ответов

историческая причина заключается в том, что большинство реализаций C (компиляторов) просто использовали любое поведение переполнения, которое было проще всего реализовать с целочисленным представлением, которое оно использовало. Реализации C обычно использовали одно и то же представление, используемое ЦП, поэтому поведение переполнения следует из целочисленного представления, используемого ЦП.

на практике, это только представления для значений, которые могут отличаться в зависимости от реализации: дополнения, дополнения two, знак-величина. Для беззнакового типа нет причин для стандарта разрешать изменение, потому что существует только одно очевидное двоичное представление (стандарт разрешает только двоичное представление).

C99 6.2.6.1: 3:

значения, хранящиеся в беззнаковых битовых полях и объектах типа unsigned char, должны быть представлены с использованием чистой двоичной нотации.

C99 6.2.6.2:2:

Если знак один бит, значение должно быть изменено одним из следующих способов:

— соответствующее значение со знаком бит 0 отрицательная (знак и величину);

— бит знака имеет значение — (2 N ) (два);

— бит знака имеет значение — (2 N — 1) (один дополнит).

В настоящее время все процессоры используют представление дополнения two, но подписанное арифметическое переполнение остается неопределенным, и создатели компилятора хотят, чтобы оно оставалось неопределенным, потому что они используют эту неопределенность, чтобы помочь с оптимизацией. Например этот блоге Ян Лэнс Тейлор или это жалоба Агнер Фог, и ответы на его сообщение об ошибке.

помимо хорошего ответа Паскаля (который, я уверен, является основной мотивацией), также возможно, что некоторые процессоры вызывают исключение при переполнении целого числа со знаком, что, конечно, вызовет проблемы, если компилятору придется «организовать другое поведение» (например, использовать дополнительные инструкции для проверки потенциального переполнения и вычислять по-разному в этом случае).

также стоит отметить, что» неопределенное поведение «не означает»не работает». Это означает, что реализация в этой ситуации можно делать все, что угодно. Это включает в себя «правильные вещи», а также «вызов полиции» или «сбой». Большинство компиляторов, когда это возможно, выберут «сделать правильно», предполагая, что это относительно легко определить (в данном случае это так). Однако, если у вас есть переполнения в расчетах, важно понять, что это на самом деле приводит к, и что компилятор может сделать что-то другое, чем вы ожидаете (и что это может очень зависеть от компилятора версия, настройки оптимизации и т. д.).

в дополнение к другим упомянутым вопросам, наличие беззнаковой математической обертки заставляет целочисленные типы беззнаковых вести себя как абстрактные алгебраические группы (что означает, среди прочего, для любой пары значений X и Y , там будет существовать какое-то другое значение Z такое, что X+Z будет, если правильно разыграть, равной Y и Y-Z будет, если правильно разыграть, равной X ). Если значения без знака были просто типами расположения хранилища, а не типами промежуточных выражений (например, если они были нет беззнакового эквивалента самого большого целочисленного типа, а арифметические операции над беззнаковыми типами вели себя так, как если бы они были сначала преобразованы в более крупные подписанные типы, тогда не было бы необходимости в определенном поведении обертывания, но трудно выполнять вычисления в типе, который не имеет, например, аддитивного обратного.

это помогает в ситуациях, когда поведение обертывания действительно полезно — например, с порядковыми номерами TCP или определенными алгоритмами, такими как хэш расчет. Это также может помочь в ситуациях, когда необходимо обнаружить переполнение, поскольку выполнение вычислений и проверка переполнения часто проще, чем проверка заранее, будут ли они переполнены, особенно если вычисления включают самый большой доступный целочисленный тип.

прежде всего, обратите внимание, что C11 3.4.3, как и все примеры и примечания для ног, не является нормативным текстом и поэтому не имеет отношения к цитированию!

соответствующий текст, который утверждает, что переполнение целых чисел и поплавков является неопределенным поведением, таков:

C11 6.5 / 5

Если исключительное условие происходит во время оценки выражение (То есть, если результат не определен математически или не в пределах представимого значения для его типа), поведение неопределено.

разъяснение относительно поведения целых типов без знака, в частности, можно найти здесь:

Читать еще:  Http 400 ошибочный запрос internet explorer

C11 6.2.5 / 9

диапазон неотрицательных значений целочисленного типа со знаком является поддиапазоном соответствующего целочисленного типа без знака и представления одно и то же значение в каждом типе одно и то же. Вычисление, включающее беззнаковые операнды не может переполниться, потому что не может быть представленный результирующим целочисленным типом без знака уменьшается по модулю число, которое на единицу больше наибольшего значения, которое может быть представлен результирующим типом.

Это делает целочисленные типы без знака частным случаем.

также обратите внимание, что есть исключение, если какой-либо тип преобразовать к знаковому типу, и старое значение больше не может быть представлено. Поведение тогда просто определяется реализацией, хотя сигнал может быть поднят.

C11 6.3.1.3

6.3.1.3 целые числа со знаком и без знака

, когда значение целого числа type преобразуется в другой целочисленный тип, отличный от _Bool, если значение может быть представлено новым типом, оно не изменяется.

в противном случае, если новый тип без знака, значение преобразуется путем многократное добавление или вычитание одного больше максимального значения, которое может быть представлен в новом типе до тех пор, пока значение не окажется в диапазоне новый тип.

в противном случае новый тип будет подписан, а значение не может быть представлен в нем; либо результат реализации или реализации определенного сигнала повышается.

возможно, еще одна причина определения арифметики без знака заключается в том, что беззнаковые числа образуют целые числа по модулю 2^n, где n-ширина беззнакового числа. Неподписанные числа — это просто целые числа, представленные двоичными цифрами вместо десятичных. Выполнение стандартных операций в модульной системе хорошо изучено.

цитата OP ссылается на этот факт, но также подчеркивает тот факт, что существует только один, однозначный, логический способ представления без знака целые числа в двоичном коде. Напротив, подписанные номера чаще всего представлены с использованием дополнения two, но возможны и другие варианты, как описано в стандарте (раздел 6.2.6.2).

представление дополнения Two позволяет некоторым операциям иметь больше смысла в двоичном формате. Например, приращение отрицательных чисел то же самое, что и для положительных чисел (ожидать в условиях переполнения). Некоторые операции на уровне машины могут быть одинаковыми для знаковых и беззнаковых чисел. Однако, при интерпретации результата этих операций некоторые случаи не имеют смысла-положительное и отрицательное переполнение. Кроме того, результаты переполнения различаются в зависимости от базового подписанного представления.

Почему поведение unsigned integer overflow определено, а signed integer overflow-нет?

Переполнение целых чисел без знака хорошо определяется стандартами C и C++. Например, стандарт C99 ( §6.2.5/9 ) гласит:

Вычисление с использованием неподписанных операндов никогда не может переполниться, потому что результат, который не может быть представлен результирующим целочисленным типом без знака, является уменьшенное по модулю число, которое на единицу больше самого большого значения, которое может быть представлен результирующим типом.

Однако оба стандарта утверждают, что переполнение целого числа со знаком является неопределенным поведением. Опять же, из стандарта C99 ( §3.4.3/1 )

Примером неопределенного поведения является поведение при переполнении целых чисел

Есть ли историческая или (еще лучше!) а техническая причина такого несоответствия?

5 Ответов

Историческая причина заключается в том, что большинство реализаций C (компиляторов) просто использовали любое поведение переполнения, которое было проще всего реализовать с использованием целочисленного представления. Реализации C обычно используют то же самое представление, что и CPU — поэтому поведение переполнения следует из целочисленного представления, используемого CPU.

На практике это только представления для знаковых значений, которые могут отличаться в зависимости от реализации: дополнение одного, дополнение двух, знак-величина. Для беззнакового типа стандарт не допускает вариации, поскольку существует только одно очевидное двоичное представление (стандарт допускает только двоичное представление).

С99 6.2.6.1:3 :

Значения, хранящиеся в беззнаковых битовых полях и объектах типа unsigned char, должны быть представлены с использованием чистой двоичной нотации.

С99 6.2.6.2:2 :

Если знаковый бит равен единице, то значение должно быть изменено одним из следующих способов:

— соответствующее значение со знаком бит 0 отрицается ( знак и величина );

— знаковый бит имеет значение −(2 N ) (дополнение двух );

— знаковый бит имеет значение −(2 N -1) (одно дополнение).

В настоящее время все процессоры используют представление дополнения two, но знаковое арифметическое переполнение остается неопределенным, и разработчики компиляторов хотят, чтобы оно оставалось неопределенным, потому что они используют эту неопределенность для помощи в оптимизации. Смотрите, например, этот пост в блоге Яна Лэнса Тейлора или эту жалобу Агнера Фога, а также ответы на его сообщение об ошибке.

Помимо хорошего ответа Pascal (который, я уверен, является основной мотивацией), также возможно, что некоторые процессоры вызывают исключение при переполнении целого числа со знаком, что, конечно, вызовет проблемы, если компилятор должен будет «arrange for another behaviour» (например, использовать дополнительные инструкции для проверки потенциального переполнения и вычислять по-другому в этом случае).

Также стоит отметить, что «undefined behaviour» не означает «doesn’t work». Это означает, что реализация может делать в этой ситуации все, что ей заблагорассудится. Это включает в себя выполнение «the right thing», а также «calling the police» или «crashing». Большинство компиляторов, когда это возможно, выберут «делать правильные вещи», предполагая, что это относительно легко определить (в данном случае это так). Однако, если у вас есть переполнения в вычислениях, важно понять, что это на самом деле приводит к тому, что компилятор MAY делает что-то другое, чем вы ожидаете (и что это может очень сильно зависеть от версии компилятора, настроек оптимизации и т. д.).

Прежде всего, обратите внимание, что C11 3.4.3, как и все примеры и сноски, не является нормативным текстом и поэтому не имеет отношения к цитированию!

Соответствующий текст, который утверждает, что переполнение целых чисел и плавающих чисел является неопределенным поведением, является следующим:

С11 6.5/5

Если исключительное состояние возникает во время оценки выражение (То есть, если результат не определен математически или не в диапазоне представимых значений для своего типа), поведение не определено.

Пояснение относительно поведения целочисленных типов без знака в частности можно найти здесь:

С11 6.2.5/9

Диапазон неотрицательных значений целочисленного типа со знаком является поддиапазоном соответствующего целочисленного типа без знака, а также представление одно и то же значение в каждом типе является одним и тем же. Вычисление с участием неподписанные операнды никогда не могут переполняться, потому что результат, который не может быть представленный в результате беззнаковый целочисленный тип уменьшается по модулю число, которое на единицу больше самого большого значения, которое может быть представлен результирующим типом.

Это делает целочисленные типы без знака особым случаем.

Также обратите внимание, что существует исключение, если какой-либо тип преобразуется в знаковый тип, и старое значение больше не может быть представлено. Поведение тогда просто определяется реализацией, хотя сигнал может быть поднят.

С11 6.3.1.3

6.3.1.3 целые числа со знаком и без знака

Когда значение с целым числом тип преобразуется в другой целочисленный тип, отличный от _Bool, если значение может быть представлено новым типом, оно остается неизменным.

В противном случае, если новый тип не имеет знака, значение преобразуется с помощью многократное добавление или вычитание одного больше максимального значения, которое может быть представлен в новом типе до тех пор, пока значение не окажется в диапазоне новый тип.

Читать еще:  Проверка диска на ошибки chkdsk

В противном случае новый тип будет подписан и значение не может быть представлен в нем; либо результат является определяется реализация или вызывается определенный реализацией сигнал.

В дополнение к другим упомянутым проблемам, наличие unsigned math wrap заставляет целочисленные типы без знака вести себя как абстрактные алгебраические группы (это означает, что, среди прочего , для любой пары значений X и Y будет существовать некоторое другое значение Z , такое что X+Z будет, если правильно привести, равно Y и Y-Z будет, если правильно привести, равно X ). Если бы неподписанные значения были просто типами расположения хранилища, а не промежуточными типами выражений (например если бы не было беззнакового эквивалента самого большого целочисленного типа, а арифметические операции над беззнаковыми типами вели бы себя так, как если бы они были сначала преобразованы в более крупные знаковые типы, то не было бы так много необходимости в определенном поведении обтекания, но трудно делать вычисления в типе, который не имеет, например, аддитивного обратного.

Это помогает в ситуациях, когда поведение обтекания действительно полезно — например, с последовательными номерами TCP или определенными алгоритмами, такими как вычисление hash. Это также может помочь в ситуациях, когда необходимо обнаружить переполнение, так как выполнение вычислений и проверка переполнения часто проще, чем проверка заранее, будут ли они переполнены, особенно если вычисления включают самый большой доступный целочисленный тип.

Возможно, еще одна причина для определения беззнаковой арифметики заключается в том, что беззнаковые числа образуют целые числа по модулю 2^n, где n-ширина беззнакового числа. Беззнаковые числа-это просто целые числа, представленные двоичными цифрами вместо десятичных. Выполнение стандартных операций в модульной системе хорошо изучено.

Цитата OP ссылается на этот факт, но также подчеркивает тот факт, что существует только один, однозначный, логический способ представления беззнаковых целых чисел в двоичном формате. Напротив, знаковые числа чаще всего представлены с помощью дополнения two, но возможны и другие варианты, описанные в стандарте (раздел 6.2.6.2).

Представление дополнения Two позволяет некоторым операциям иметь больше смысла в двоичном формате. E.g., приращение отрицательных чисел то же самое, что и для положительных чисел (ожидайте в условиях переполнения). Некоторые операции на машинном уровне могут быть одинаковыми для подписанных и неподписанных чисел. Однако при интерпретации результата этих операций некоторые случаи не имеют смысла — положительное и отрицательное переполнение. Кроме того, результаты переполнения различаются в зависимости от базового знакового представления.

Похожие вопросы:

Кажется, это происходит постоянно. Например: (apply * (range 1 101)) дает мне ошибку ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374) В то время как в.

Я получил следующий стек trace через ACRA . Galaxy Note II, Android 4.1.2 : android.database.sqlite.SQLiteException: integer overflow (code 1) at.

Я использую следующую функцию, чтобы попытаться создать 64-разрядный hash строки, но это не удается с ArithmeticException, хотя я использую версию unchecked арифметических операторов. user>.

Я читал этот вопрос и один из комментариев упомянул C signed-integer-based атак . Я знаю, что такое переполнение int , но я не понимаю, как это можно использовать для атаки на программу. что именно.

Я получаю: предупреждение: предполагая, что знаковое переполнение не происходит, если предположить, что (X + c) #include
int absolute(int i) < int j = i

Integer overflow ошибка

не надо фантазий.
в правой части выражения у вас 2 константы. числовые константы по умолчанию имеют тип int. результат любого выражения (промежуточные результаты вычислений) по умолчанию будет совпадать с int (если все составные части меньше или равны int) или с наибольшим «размером типа» входящих в выражение элементов — в вашем случае int. и лишь после всех вычислений результат преобразуется в тип, необходимый для левой части, т.е. для переменной long

естественно, при умножении int * int результат в int может не поместиться — о чем компилятор вам и говорит. хотите избавиться от проблемы — сделайте так, чтобы какой-то элемент в правой части имел тип long, например так:

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
удивительно, но при взгляде на многих сверху ничего не меняется.

Сборка печатных плат от $88 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Последний раз редактировалось smac Сб дек 13, 2008 15:37:22, всего редактировалось 1 раз.

15 апреля приглашаем на вебинар, который будет интересен разработчикам и инженерам-схемотехникам, интересующимся тенденциями рынка, новыми перспективными решениями для соединений «провод-провод», «провод-плата», «плата-плата». Для инженеров КИПиА и IT будут освещены уникальные решения Molex для «удлинения» интерфейсов HDMI, DisplayPort и USB даже в условиях сильного зашумления, а также семейство бесконтактных датчиков Contrinex. Помимо этого, будет уделено внимание дальнейшему развитию направления антенн, где Molex имеет ряд интересных и уникальных решений.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
удивительно, но при взгляде на многих сверху ничего не меняется.

Компактные источники питания Mornsun изготавливаются как в виде миниатюрных открытых печатных плат (семейство LS с мощностью 1…15 Вт; семейство LO мощностью 3…65 Вт), устанавливаемых на основную плату устройства, так и в виде корпусированных модулей с повышенным уровнем защиты и надежности (семейства LD/LH мощностью 2…60 Вт).

Естественно можно, только вот речь шла не о сложении, а об умножении, а там одного флага переноса не достаточно

Я предполагаю.
Тогда попробуй, скомпилить код с фрагментом PORTC = PORTD/PORTB.
и посмотри какая весёлая хрень получается.

И вообще из темы не совсем понятно: «warning» — это разве ошибка!?

Последний раз редактировалось pirotehnick Сб дек 13, 2008 17:46:08, всего редактировалось 1 раз.

странные хедеры для винавр
там avr/io.h должно быть
у тебя какая версия?

писать надо unsigned long int и переменная должна быть внутри мейн (если она не глобальная)

pirotehnick, в вашем «смешном» примере нет ничего удивительного. вы невнимательно прочитали мое сообщение. повторю: в Си все значения сначала приводятся к типу int (если иное не сказано) или к типу наибольшего элемента, затем производятся вычисления, а затем результат приводится к типу переменной, куда он записывается.

теперь ваш пример PORTC = PORTD/PORTB.
все переменные имеют тип unsigned char. значит, сначала PORTD и PORTB будут приведены к типу int, причем самое смешное в том, что беззнаковый байт будет преобразован в знаковый int, затем будет произведено деление, а затем от результата будет отброшен старший байт, а младший будет выведен в PORTC. надеюсь, вам не надо объяснять, что 0xFF будет превращено таким образом в -1, ну, и потом после деления будет что-то невероятное, а его младший байт — и того удивительнее.

что касается удивления в вычислении констаны. да, компилятор подставит конкретное число. только это число получается с переполнением int — вот он и предупреждает, что хрень какая-то будет в итоге (типа как в вашем примере с портами).

warning — это не ошибка, а предупреждение. но в некоторых случах это хуже ошибки. предупреждение может означать, что программа будет работать, но как именно — неизвестно. и в данном случае смысл как раз такой.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
удивительно, но при взгляде на многих сверху ничего не меняется.

Ссылка на основную публикацию
ВсеИнструменты
Adblock
detector
×
×