6.56 Встроенные функции для выполнения арифметических операций с проверкой переполнения ¶
Следующие встроенные функции позволяют выполнять простые арифметические операции вместе с проверкой того, произойдет ли переполнение при их выполнении.
-
Встроенная функция:
bool__builtin_add_overflow(type1 a, type2 b, type3 *res)¶ -
Встроенная функция:
bool__builtin_sadd_overflow(int a, int b, int *res)¶ -
Встроенная функция:
bool__builtin_saddl_overflow(long int a, long int b, long int *res)¶ -
Встроенная функция:
bool__builtin_saddll_overflow(long long int a, long long int b, long long int *res)¶ -
Встроенная функция:
bool__builtin_uadd_overflow(unsigned int a, unsigned int b, unsigned int *res)¶ -
Встроенная функция:
bool__builtin_uaddl_overflow(unsigned long int a, unsigned long int b, unsigned long int *res)¶ -
Встроенная функция:
bool__builtin_uaddll_overflow(unsigned long long int a, unsigned long long int b, unsigned long long int *res)¶ -
Эти встроенные функции преобразуют первые два операнда в целые типы бесконечной точности со знаком и выполняют сложение над этими преобразованными операндами. Результат затем приводится к типу, на который указывает третий аргумент-указатель, и сохраняется там. Если сохранённый результат равен результату бесконечной точности, встроенные функции возвращают
false, в противном случае они возвращаютtrue. Поскольку сложение выполняется в бесконечной точности со знаком, эти встроенные функции имеют полностью определённое поведение для всех значений аргументов.Первая встроенная функция допускает произвольные целые типы для операндов, а тип результата должен быть указателем на некоторый целочисленный тип, кроме перечислений или логических типов; остальные встроенные функции имеют явные целочисленные типы.
Компилятор попытается использовать аппаратные инструкции для реализации этих встроенных функций, где это возможно, например, условный переход на переполнение после сложения, условный переход по переносу и т. д.
-
Встроенная функция:
bool__builtin_sub_overflow(type1 a, type2 b, type3 *res)¶ -
Встроенная функция:
bool__builtin_ssub_overflow(int a, int b, int *res)¶ -
Встроенная функция:
bool__builtin_ssubl_overflow(long int a, long int b, long int *res)¶ -
Встроенная функция:
bool__builtin_ssubll_overflow(long long int a, long long int b, long long int *res)¶ -
Встроенная функция:
bool__builtin_usub_overflow(unsigned int a, unsigned int b, unsigned int *res)¶ -
Встроенная функция:
bool__builtin_usubl_overflow(unsigned long int a, unsigned long int b, unsigned long int *res)¶ -
Встроенная функция:
bool__builtin_usubll_overflow(unsigned long long int a, unsigned long long int b, unsigned long long int *res)¶ -
Эти встроенные функции аналогичны встроенным функциям проверки переполнения при сложении, за исключением того, что они выполняют вычитание, вычитая второй аргумент из первого, вместо сложения.
-
Встроенная функция:
bool__builtin_mul_overflow(type1 a, type2 b, type3 *res)¶ -
Встроенная функция:
bool__builtin_smul_overflow(int a, int b, int *res)¶ -
Встроенная функция:
bool__builtin_smull_overflow(long int a, long int b, long int *res)¶ -
Встроенная функция:
bool__builtin_smulll_overflow(long long int a, long long int b, long long int *res)¶ -
Встроенная функция:
bool__builtin_umul_overflow(unsigned int a, unsigned int b, unsigned int *res)¶ -
Встроенная функция:
bool__builtin_umull_overflow(unsigned long int a, unsigned long int b, unsigned long int *res)¶ -
Встроенная функция:
bool__builtin_umulll_overflow(unsigned long long int a, unsigned long long int b, unsigned long long int *res)¶ -
Эти встроенные функции аналогичны встроенным функциям проверки переполнения при сложении, за исключением того, что они выполняют умножение вместо сложения.
Следующие встроенные функции позволяют проверять, приведет ли простая арифметическая операция к переполнению.
-
Встроенная функция:
bool__builtin_add_overflow_p(type1 a, type2 b, type3 c)¶ -
Встроенная функция:
bool__builtin_sub_overflow_p(type1 a, type2 b, type3 c)¶ -
Встроенная функция:
bool__builtin_mul_overflow_p(type1 a, type2 b, type3 c)¶ -
Эти встроенные функции похожи на
__builtin_add_overflow,__builtin_sub_overflow, или__builtin_mul_overflow, за исключением того, что они не сохраняют результат арифметической операции нигде, и последний аргумент — это не указатель, а какое-то выражение целого типа, отличного от перечислимого или булевого типа.Встроенные функции преобразуют первые два операнда в целые числа со знаком бесконечной точности и выполняют сложение над этими преобразованными операндами. Результат затем приводится к типу третьего аргумента. Если результат приведения равен результату бесконечной точности, встроенные функции возвращают
false, в противном случае они возвращаютtrue. Значение третьего аргумента игнорируется, оцениваются только побочные эффекты в третьем аргументе, и никакого повышения целых аргументов не выполняется для последнего аргумента. Если третий аргумент является полем битов, тип, используемый для приведения результата, имеет точность и знак данного поля битов, а не точность и знак базового типа.Например, следующую макрос можно использовать для проверки на этапе компиляции, переполнит ли сложение двух константных целых чисел, и выполнить сложение только тогда, когда это известно как безопасное действие и не приведет к предупреждению -Woverflow.
#define INT_ADD_OVERFLOW_P(a, b) \ __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0) enum { A = INT_MAX, B = 3, C = INT_ADD_OVERFLOW_P (A, B) ? 0 : A + B, D = __builtin_add_overflow_p (1, SCHAR_MAX, (signed char) 0) };Компилятор попытается использовать аппаратные инструкции для реализации этих встроенных функций, где это возможно, например, условный переход на переполнение после сложения, условный переход на перенос и т.д.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-11.4.0/gcc/Integer-Overflow-Builtins.html