I'm sure you are correct about the aliasing being undefined behavior. However, Microsoft's attitude towards certain types of undefined is quite different from the gcc/clang attitude and VC++ (more or less) promise not to break your program if you break the aliasing rules.
gcc/clang are within their rights to break programs that break the aliasing rules, but VC++ is not required to do so and they choose not to.
There have been some excellent articles talking about how the current state of undefined behavior as understood by gcc/clang is crazy. One that I like is this one:
http://blog.regehr.org/archives/761
Obviously some types of undefined behavior cannot be 'normalized', such as use-after-free, but treating the aliasing in that bug as undefined behavior is a committee decision that many developers think is ill advised.
Another recent article that I can't find pokes some holes in the idea that the latitude given to compilers by undefined behavior improves performance.
For your second example of undefined behavior I'm afraid I don't understand. Are you saying that even if the line of code that aliases the array is removed that "if (key[0] != 42)" is still undefined behavior? If so please explain. You say "the type AS ACTUALLY WRITTEN is not char" but I'm not sure what type you are referring to, and if you mean '42' that is true but not relevant because in a comparison between key[0] and '42' "key[0]" is converted to int by the standard integral conversions and then a particularly boring comparison is done.
If that code is undefined then the standards committee is definitely crazy and no code is conforming.
I should have written "AS ACTUALLY STORED" to be clear. You store an int into memory. That memory happens to be described as a char array, but you stored an int as an int. It's an int. It will always be an int, and you can only legitimately interpret it as an int. (Had you stored to key[0] in the normal way then the value would have been be stored as a char instead.)
Reading it out as a long or float would be prohibited by aliasing rules, even if those types happen to be the same size. When you do "if(key[0] != 42)" you are reading out the value in key[0] as char, which is OK, but the content is undefined. You can't legitimately compare an undefined value with 42.
There is a special exception for char. You don't violate the aliasing rules when you load part of the int as a char. This special exception is very limited. It's for implementing functions like memcpy. (but not of that name, since "memcpy" is reserved)
The special exception doesn't make the data meaningful when loaded as char. The bits could be in any order. When you load part of an int into a char, the only legitimate thing you can do with it is to store it as if doing a memcpy.
Depending on how you read the C standard, you might even need an unsigned char to avoid trap representations. People argue this both ways.
gcc/clang are within their rights to break programs that break the aliasing rules, but VC++ is not required to do so and they choose not to.
There have been some excellent articles talking about how the current state of undefined behavior as understood by gcc/clang is crazy. One that I like is this one: http://blog.regehr.org/archives/761
Obviously some types of undefined behavior cannot be 'normalized', such as use-after-free, but treating the aliasing in that bug as undefined behavior is a committee decision that many developers think is ill advised.
Another recent article that I can't find pokes some holes in the idea that the latitude given to compilers by undefined behavior improves performance.
For your second example of undefined behavior I'm afraid I don't understand. Are you saying that even if the line of code that aliases the array is removed that "if (key[0] != 42)" is still undefined behavior? If so please explain. You say "the type AS ACTUALLY WRITTEN is not char" but I'm not sure what type you are referring to, and if you mean '42' that is true but not relevant because in a comparison between key[0] and '42' "key[0]" is converted to int by the standard integral conversions and then a particularly boring comparison is done.
If that code is undefined then the standards committee is definitely crazy and no code is conforming.