Беззнаковые имеют 1) более высокие максимумы и 2) определенные, переполнение по кругу.
Если с бесконечной точностью
(unxigned_c = unsigned_a + unsinged_b) >= UINT_MAX
, тогда unsigned_c
будет уменьшено по модулю UINT_MAX+1
:
#include <limits.h>
#include <stdio.h>
int main()
{
printf("%u\n", UINT_MAX+1); //prints 0
printf("%u\n", UINT_MAX+2); //prints 1
printf("%u\n", UINT_MAX+3); //prints 2
}
Аналогичная вещь происходит с вами, сохраняя подписанные значения в неподписанные.В этом случае применяется 6.3.1.3p2 - к значению концептуально добавляется UINT_MAX+1
.
С другой стороны, для типов со знаком переполнение не определено, что означает, что если выПозвольте этому случиться, ваша программа больше не является правильно сформированной, и стандарт не дает никаких гарантий относительно ее поведения.Компиляторы используют это для оптимизации , предполагая, что этого никогда не произойдет.
Например, если вы компилируете
#include <limits.h>
#include <stdio.h>
__attribute__((noinline,noclone)) //or skip the attr & define it in another tu
_Bool a_plus1_gt_b(int a, int b) { return a + 1 > b; }
int main()
{
printf("%d\n", a_plus1_gt_b(INT_MAX,0)); //0
printf("%d\n", INT_MAX+1); //1
}
на gcc с -O3
, это оченьскорее всего печать
1
-2147483648