I'm trying to understand strict aliasing rule for C and C++. I've asked lots of questions about this and done a bit of reading on it but I just want to clarify something.
// void* can alias any other type:
int anInt;
void* pToVoid = (void*)&anInt; // Allowed
// So can char*
char* pToChar = (char*)&anInt; // Allowed
Pointer to any type can alias void*, that's why we can do something like:
int* myNewInt = (int*)malloc(sizeof(int));
But:
(Question 1) Can any pointer type alias char pointer?
char myChars[4];
int* pInt = (int*)myChars; // Is this allowed?
// I'm guessing so because this is how we create buffers
float* pFloat = (float*) pInt; // I know this is strict aliasing violation
Question 2: Also when aliasing any pointer type to a char or void pointer type we need ensure correct alignment, right? There's no guarantee on the stack that a char or char array will be aligned as we get it from new or malloc, right?
My third question is if the strict aliasing rule is violated when you cast a pointer or when a pointer aliases the same memory? For example:
struct MyStruct
{
int myInt;
float myFloat;
};
int main()
{
MyStruct myStructObj;
float* pFloat = &myStructObj.myInt; // This is aliasing the wrong type, not allowed
// However if I move the float* then it no longer aliases the wrong type
pFloat += 1;
// Now the pointer points to the right type. However is it now too late? My program
// has UB because I first aliased the pointer in the first place?
// On the other hand I assume this is allowed though:
float pFloat = (float*)(((char*)&myStructObj.myInt) + sizeof(int));
// This way the float pointer never aliases the int, the int pointer is
// first cast to char*, then char* to float*, which I assume is allowed.
}
In other words is the strict aliasing rule about accessing the same memory or assigning different pointer types? Because if it's only about memory access then my example of assigning the float* to the int* is fine because I move it first, right?
Edit: It's been pointed out that the aliasing rules are different for C and C++, therefore I've tagged this to be about C++.