int this_is_a_fairly_long_variable_name_1;
int this_is_a_fairly_long_variable_name_2;
Why? Because section 5.2.4.1 requires implementations to support at least 32 significant characters in external identifiers and section 6.4.2.1 says "If two identifiers differ only in nonsignificant characters, the behavior is undefined."
These ones may be more "obvious", but:
Given e.g. int a[4][5] then accessing a[1][7] is undefined even though one might assume it's like accessing a[2][2]
x << -3 is undefined behaviour though logically one might assume it should be equivalent to x >> 3
And the classic, very common newbie use of "fflush(stdin);" is also undefined.
Not saying anything about the other things, but this (in my opinion) is something that should raise eyebrows. At least to me personally that looks rather weird.
I think the second example may contain UB on a <=32-bit architecture (right shift by a value greater or equal to the number of bits), or at least this is UB in C++. On a 64-bit architecture it would be fine (but the result would not be 0).
(It's also not unique to C)
It's not obvious which actions are atomic.
And I would never excrete such a line of code without automatically thinking "hmmm.. does this really do what I think it does?"
This is an undefined operation in almost all programming languages.
There is no intrinsic reason why a[i] = i++ has to result in undefined behavior.
if i is signed, this is undefined. You'd think it's just a loop though.
while (1) for(;;)