Как опубликовать исключение арифметического переполнения в C/C++ с удобством компилятора
Когда я запускаю программу Android, я нахожу исключение Native. Я считаю, что это исключение происходит из строки кода, которая может вызвать арифметическое переполнение. Но вопрос в том, что арифметическое переполнение не будет обычно сообщаться в C/C++, как минимум, когда я тестирую его с g++ и ОС Linux.
Я предполагаю, что переполнение будет сообщено из-за некоторых дополнительных функций компилятора при компиляции Android. Точно мой вопрос заключается в том, как заставить следующий код публиковать некоторые исключения при его запуске.
int main(){
size_t size = 0;
size--;
return 0;
}
2 ответа
size_t
это тип без знака. Здесь никогда не бывает арифметического переполнения. Вместо этого результат всех вычислений для неподписанных типов переносится в диапазон значений, как будто путем многократного сложения или вычитания более одного максимального значения. Это означает, что после size--
, size
будет держать значение SIZE_MAX
,
С другой стороны, целочисленное переполнение со знаком имеет неопределенное поведение. Возможно, вам будет интересно поймать это. GCC поддерживает перехват неопределенного поведения, связанного с целочисленным переполнением со знаком. Учитывая следующую программу, неопределенное поведение происходит, когда size = INT_MIN
уменьшается:
#include <stdio.h>
#include <limits.h>
volatile int size = INT_MIN;
int main(){
size--;
printf("%d\n", size);
return 0;
}
Скомпилируйте программу с
% gcc foo.c -Wall -Wextra -Woverflow -fsanitize=undefined
и не возникает ошибка. Если вы запустите его, вы увидите
% ./a.out
foo.c:5:9: runtime error: signed integer overflow: -2147483648 - 1
cannot be represented in type 'int'
2147483647
Также возможно настроить это, чтобы отменить при первой неисправности, но я не думаю, что это так же полезно.
К сожалению нет.
Также выберите язык. Переполнение со знаком и завершение без знака невозможно обнаружить с помощью языковых механизмов. Вы можете, конечно, добавить несколько ifs себя