The C Standard explicitly specifies signed integer overflow as having undefined behavior. Yet most CPUs implement signed arithmetics with defined semantics
Here's an actual little benchmark, bubble sort. I've compared timings without/with -fwrapv (which means the overflow is UB/not UB). Here are the results (seconds):
-O3 -O3 -fwrapv -O1 -O1 -fwrapv
Machine1, clang 5.2 6.3 6.8 7.7
Machine2, clang-8 4.2 7.8 6.4 6.7
Machine2, gcc-8 6.6 7.4 6.5 6.5
As you can see, the not-UB (-fwrapv) version is almost always slower, the largest difference is pretty big, 1.85x.
Here's the code. Note, that I intentionally chose an implementation, which should produce a larger difference for this test.
#include
#include
void bubbleSort(int *a, long n) {
bool swapped;
for (int i = 0; i < n-1; i++) {
swapped = false;
for (int j = 0; j < n-i-1; j++) {
if (a[j] > a[j+1]) {
int t = a[j];
a[j] = a[j+1];
a[j+1] = t;
swapped = true;
}
}
if (!swapped) break;
}
}
int main() {
int a[8192];
for (int j=0; j<100; j++) {
for (int i=0; i<8192; i++) {
a[i] = rand();
}
bubbleSort(a, 8192);
}
}