We know that logical-AND operator (&&) guarantees left-to-right evaluation.
But I am wondering if the compiler optimizer can ever reorder the me
First of all I take it as granted that && stands for the built-in version of the logical AND operator.
I think that the compiler may legitimately perform evaluations from the right-hand-side sub-expression of the && operator before it completes evaluation of the left-hand side, but in a manner that wouldn't change the semantics of the full expression.
For your example, C++ compiler is allowed to introduce reordering under the following conditions:
a is a primitive pointer (i.e. its type is not a class that overloads operator*). b is a primitive pointer (i.e. its type is not a class that overloads operator->)b is known to be dereferenceable regardless of the value of *aIf 1. doesn't hold, then the user-defined operator* may have a side effect of changing the value of b->foo.
If 2. doesn't hold, then the user-defined operator-> may change the value of *a, or throw, or produce another observable side-effect (e.g. print something) that shouldn't have shown up had *a evaluated to false.
If 3. cannot be proved through static analysis, then reordering would introduce undefined behaviour that is not in the original program.
C compiler, naturally, only needs to perform the 3rd check.
In fact, even if *a and b->foo involve operator overloading, C++ compiler can still reorder some instructions when those operators can be inlined and the compiler doesn't detect anything dangerous.