More undefined behavior in C
Shifting too far, reading uninitialized memory, dividing by zero — and the guards.
#include <limits.h>
int shift_safely(unsigned int value, unsigned int by) {
if (by >= sizeof(unsigned int) * CHAR_BIT) {
return 0;
}
return (int) (value << by);
}
int divide_safely(int a, int b, int *out) {
if (b == 0 || (a == INT_MIN && b == -1)) {
return 0;
}
*out = a / b;
return 1;
}
int initialized(void) {
int value = 0;
return value;
}
How it works
- Shifting by the width of the type is undefined, not zero.
INT_MIN / -1overflows, so division needs two checks.- An uninitialized read may return anything at all.
Keywords and builtins used here
divide_safelyifinitializedintreturnshift_safelysizeofunsignedvoid
The run, in numbers
- Lines
- 21
- Characters to type
- 345
- Tokens
- 111
- Three-star pace
- 105 tpm
At the three-star pace of 105 tokens a minute, this run takes about 63 seconds.
Step 3 of 3 in Undefined behavior, step 10 of 13 in Unions, bitfields & undefined behavior.