Are void** and int** compatible types?
Your understanding is correct: they are not "compatible" types as the language spec defines that.
I expect the code below to emit a warning for a violation of the strict aliasing rule, on the line where ptrs is cast to void ** and dereferenced.
Why?
Yes, you have a violation of the strict aliasing rule. However, the SAR is a semantic rule, not a language constraint, so the language specification does not require conforming implementations to diagnose violations (much less non-conforming ones). Moreover, although in the example code, the violation could be detected at compilation time, that's not universally true of SAR violations.
Furthermore, in this particular case, the program will likely work just fine on many systems unless the compiler is wantonly perverse, because typically, all object pointers have the same representation.
With Wstrict-aliasing=1
, the warning dereferencing type-punned pointer might break strict-aliasing rules is emitted.
Which is perfectly reasonable, since the strict-aliasing rule is in fact violated.
However, that warning goes away when setting the warning level to 2 or 3, which seems an indication that my understanding is incorrect.
No compiler is perfect, and the manual says that -Wstrict-aliasing=1
has few false negatives, not none. Moreover, it does warn about your code when optimization is not enabled.
That the compiler does not emit a diagnostic is not a sound basis for concluding that there is no issue. Especially when under some conditions it in fact does diagnose.
That enabling optimization prevents the compiler from diagnosing the strict-aliasing violation most likely reflects that at least some of its optimization passes are performed prior to the strict aliasing analysis, and that they have the effect of preventing it from recognizing this particular one.
For example, I can imagine the void_ptr
temporary being eliminated altogether, in conjunction with the (void **)
cast being adjusted or eliminated appropriately, which would optimize the strict-aliasing violation right out of the resulting intermediate representation. That's speculative, of course, but in the end, it all comes back around to the compiler not being required to diagnose the violation.
And also, I suspect, to the particular violation in this case not presenting a problem in practice for GCC-compiled code.