5 ms·
Here's a gotcha I find more interesting than strlen: Right shifting integers instead of dividing by powers of two, e.g: 1337 / 8; Becomes: 1337 >> 3; Compil
by fhd2 13y ago
Here's a gotcha I find more interesting than strlen: Right shifting integers instead of dividing by powers of two, e.g:
1337 / 8;
Becomes:
1337 >> 3;
Compilers ought to figure that one out, shouldn't they? Well if 1337 is a signed int, they can't. Shifting actually leads to different semantics for negative numbers, so this optimisation is only possible for unsigned ints. You can either do the bit shift or cast to unsigned, but it's a leaky abstraction either way.
- azernik 13y agoI'm pretty sure that the different semantics for negative signed ints (sign extension) are there to make sure it works as division. It's right-shifting for regular bit manipulation purposes that's unsafe with signed.
- icodestuff 13y agoWhether right-shift is arithmetic or logical is implementation-defined in C. The compiler (for obvious reasons) knows what hardware is available, and generally optimizes a divide by a power of two to a right-shift if arithmetic is available (as it is in most architectures), plus a check to see if the number is odd and negative (and to add 1 to the numerator if so). All of which is still faster than using the divide hardware.
- azernik 13y agoOne more instance where I just assumed that what GCC does was in the standard. Very interesting. For the curious who don't want to duplicate my look-up - right shift is by definition division by two except negative signed numbers, for which it's implementation defined. GCC on every architecture I've checked uses arithmetic shift for signed, probably because that extends the base definition to negatives.