I am trying to understand the strict aliasing rule. By reading the answer to What is the strict aliasing rule , I have some further questions. Here I borrow the example from that post:
struct Msg { uint32_t a, b; }
void SendWord(uint32_t);
void SendMessage(uint32_t* buff, uint32_t buffSize)
{
  for (uint32_t i = 0; i < buffSize; ++i) SendWord(buff[i]);
}
Now consider the following code (A):
uint32_t *buff = (uint32_t*)malloc(sizeof(Msg));
std::memset(buff, 0, sizeof(Msg));
Msg *msg = (Msg*)buff; // Undefined behavior.
for (uint32_t i = 0; i < 10; ++i)
{
  msg->a = i;
  msg->b = i + 1;
  SendMessage(buff, 2);
}
free(buff);
For the above code, the author explained what might happen due to the UB. The message sent could contain all 0s: during optimization, the compiler may assume msg and buff point to disjoint memory blocks, and then decide the writes to msg do not affect buff.
But how about the following code (B):
uint32_t *buff = (uint32_t*)malloc(sizeof(Msg));
std::memset(buff, 0, sizeof(Msg));
unsigned char *msg = (unsigned char*)buff; // Compliant.
for (uint32_t i = 0; i < sizeof(Msg); ++i)
{
  msg[i] = i + 1;
  SendMessage(buff, 2);
}
free(buff);
Is the sent message guaranteed to be as intended (as if the strict aliasing complier flag is off) ? If so, is it simply because a *char (msg) points to the same place as buff, the compiler should and will notice it, and refrain from the possible, aforementioned optimization in (A) ?
Yet then I read another comment under the post Strict aliasing rule and 'char *' pointers, saying that it is UB to use the *char pointer to write the referenced object. So again, code (B) could still result in similar, unexpected behavior ?
 
    