It's individual implementors who decide whether or not that should be
true for their implementation. That decision should be made on the basis
of what's good for their intended customers, and sometimes it's better
for to break legacy code than to make the accommodations needed to avoid
breaking it. As long as someone needs the legacy code to be compilable,
someone will maintain a compiler that has a mode that will allow it to
be compiled, but that doesn't mean that all compilers need to be able to
do so, nor even that it be the default mode for that compiler.
A real example of this happening is the MS Windows interface.
Windows are defined by opaque handles, which can be PrivateWindow *s underneath, but originally they were longs, I suspect an index into a
window table. To have any sort of encapsulation, you need to be able to hang
a pointer off a window. But Microsoft didn't provude a "Set user pointer"
function. Instead they provided a "set/set Window long", with a USER_DATA
field nicely defined.
So if a void *fitted into a long, you could hang a pointer off a window. It was
wrong, but the only alternative was to specify some sort of memory handle
scheme. Then you wouldn't have encapsulation, because your window widget would
depend on an external malloc/handle wrapper. You could get round this by
having separate malloc wrappers for each class, but then it gets even more
messy, and all to avoid a cast from a long to a void *.
So lots of widgets were built with this scheme. Now you want the code to mix
with new code. There's limited use in having a widget that can't be taken and
dropped into a new program. So just having one mode which defines long as
the same size as void * doesn't help. Of course Microsoft put in a layer of
typedefs, so the function actually takes a LONG. Then they provided a
SetWindowLongPtr() function, which, it turns out, also needs a long. But these
strategies haven't actually worked. They rarely do. Changing typedef has
too many effects to be a smooth process.
There's no easy answer. The changes needs to most code are pretty trivial,
you've just got to replace the call to get/set the user long with a call to
the latest memory hook. But it still means editing and maintaining two versions
of files.