Should compilers automatically translate operations into shortcuts? There are several coding operations that (I suspect) most compilers will change into more efficient operations at the assembly or machine code level. I have several questions about whether or not the compiler does any of this work, and if it's even best for the compiler to automatically do so.

(Note: These examples use C and C-like language syntax. However, just because i'm doing examples in C, doesn't mean I only want answers for the C compilers. I'm interested in how most major languages handle these things.)

The first is a += 1; vs a++;, where a is any integer variable. Both these codes ultimately result in the same thing (incrementing by 1), but a++ does it quicker somehow. I was self-taught for my first few languages and just never came across the a++ style, so I use the a += 1 style in all my private programming. However, of course later I discovered that a++ is more common when you only need to increment by 1. I believe the origins of it are from the old days where computers were super slow, therefore finding a shortcut for incrementing (or decrementing) by 1 was a huge deal. Now don't get me wrong, it could still make a difference today like in huge nested loops, and the most common place i see the shortcut is in loops anyway. Is there any reason why you would strictly want the slower a += 1 style? Incidentally, do most compilers automatically translate a a += 1 into a a++?

The second is dividing by a power of 2. b /= 8; can be shortcut to a simple bit shift by 3 bits to the right (towards the least significant bit, and filling in zeros on the MSB side)---as long as b is an integer. Should compilers make this translation, or is there some instance where you want the slower b /= 8 operation? Do compilers typically optimize this?

Can't think of any more simple types of shortcuts, but wouldn't be surprised if some exist.
First compilers may (and often will depending on the optimization level) do transformations far more complex than the one you describe.  You should not be concerned about the performance implication of the way you express the increment or the division before being sure that you are using a compiler for which it matters.

But there are some other implications.  Some are just stylistic (and here my recommendation is that you just follow what is the style of your organization, if you are in position to chose the style, chose one which suit you and don't second guess yourself about it every other week).  Other are semantic.

a += 1 and a++ are equivalent only if the context allows.  In C and C++, they are both expressions, and if the result of the expression is different (a += 1 is the incremented value; a++ is the non incremented value, ++a returns the incremented value).

a/8 and a&gt;&gt;3 are equivalent only if the value of a is positive or null.  For negative values, C and C++ the result is not determined by the C and C++ standards but left to the implementation(*).  The most common behavior gives the same result as a/8 for exact multiple of 8.  For negative values which are not a multiple of 8, a/8 has a result truncated towards 0 (i.e. -1/8 is 0) while a&gt;&gt;3 is truncated towards minus infinity (i.e. -1 &gt;&gt; 3 is -1).  You may know that the replacement is valid for your program but that is hard to determine for the compiler which will often not do the replacement or use a more complex one.



(*) Two reasons: the standards are defined in such a way that machines with ones' complement or sign and magnitude representation for signed values is possible and what is the natural result depend on the representation; some uncommon machines have only an unsigned shift.