Ten years ago I wold have thought you crazy to say that. But you are right, and old folks like me who have made use of/relied on details properties of particular machine storage hopefully now realize those tricks -- cuz that's what they are -- are side effects that should be avoided, not exploited.
The old justifications are mostly gone. Speed, compactness of expression, storage limitations, crappy compilers and tools -- and I only say this part to make myself more popular (lol) -- macho programming. Cleverness for cleverness' sake. I've done enough clever programming (as opposed to elegant programming, say) with good intent (and often good effect). But I dont think its a good habit at all, today, in modern languages, or in old languages we still (I still) use: C, C++.
In my current embedded work, little machines with limited resources, relying on word length and overflow off the end of a word, or using shifting to speed up math -- those are all really bad concepts.
I'm pretty sure gcc will apply those tricks if you say X = Y * 2 and X and Y are integers. THAT'S GREAT! Our language can be portable (Y * 2) and the fungible compiler output gets the gain.
LOL -- that said, representation of numbers within a machine is to me *fascinating*, as is representations of meaning of characters, numbers, symbols and their relations to glyphs, etc.
Someone has to know that stuff to make machines. The old days though are long gone, where you apply what you think are machine-dependent trickery (word length) to gain advantage with a compiler.
@b0rk