O_o
@MOS-6581:
The code, as is, from post #5 does break the "Strict Aliasing" rule. The "Strict Aliasing" rule exists to allow the compiler to make assumptions about reads and writes. Specifically, the compiler is allowed to assume that pointers and references to "incompatible types" do not address the same memory location so that code may be ordered in such a way to benefit from whatever environment is under consideration.
You have allocated some memory. The compiler has not stored a value at the memory address provided by the allocation. The compiler has not inserted an instruction for reading at the provided memory address. You have not "told" the compiler to read the provided memory address. You write a value to the memory address provided. You then write a different value to the memory address provided. Your code does indeed not read, "access", a stored value from an "incompatible type". However, the "Strict Aliasing" rule comes into play because the compiler may reorder the assignments. In other words, the "imaginary" next line which may read from either `a' or `f' exhibits undefined behavior because the compiler may have written instructions such that the integer value `42' or the floating-point value `42.0f' exists at the provided memory address. Again, the actual value at the provided memory address is undefined because the code violates the "Strict Aliasing" rule.
As I implied before you ever posted such code, that code is irrelevant with respect to a custom allocator. You are not responsible for how a client uses your memory allocator. You can do nothing if the client fails to observe the "Strict Aliasing" rule. Your job is to write a memory allocator.
Code:
void * sPool = malloc(sizeof(int) + sizeof(float)); /* just being safe with the size */
if(rand() % 2)
{
int * s = sPool;
// use `*s' only as an `int'
*s = 0;
/* ... */
printf("%d", s);
}
else
{
float * s = sPool;
// use `*s' only as an `float'
*s = 0.0f;
/* ... */
printf("%f", s);
}
Such code as this does not violate the "Strict Aliasing" rule. Yes, we do have two references to the allocated memory in both paths. However, we have only stored the address; we are not reading/writing to the same memory allocation with "incompatible types".
Again, the "Strict Aliasing" rule comes into play with pointers and references because of the referenced memory as related to code attempting reads and writes with "incompatible types".
You could have a million different pointers to the same location. If the code only ever reads the memory address as a specific object with a compatible type the code does not violate the "Strict Aliasing" rule.
Of course, the code may violate other rules such as alignment related issues, and you will have to account for such other rules. Again, you are so near the forest your vision is full of nothing but bark. You need to step back from the specific issue of "Strict Aliasing" so that you may see how all the related rules, optimizations, and how compilers ignore some of those things interrelate.
Yes. You are allowed to "construct" a new object at a specific memory address. Again, look at my code in post #2; the standard does not guarantee that the memory address referenced by both `s' variables is different. If you were not able to "construct" a different object at a specific memory address the code would exhibit "undefined behavior". Such code can not exhibit undefined behavior. (Edit: Some ancient environments didn't check the `free' parameter full null which could cause "undefined behavior", but those environments are not really relevant.) The "Strict Aliasing" rule only comes into play when you've used "aliases", different names for "incompatible types", to read and write the same address with pointers and references.
Code:
void * sPool = malloc(sizeof(int) + sizeof(float)); /* just being safe with the size */
int * s1 = sPool;
float * s2 = sPool;
Such code as this example does not violate the "Strict Aliasing" rule. The actual object, the "value" at the memory address, hasn't been read or written.
Code:
void * sPool = malloc(sizeof(int) + sizeof(float)); /* just being safe with the size */
int * s1 = sPool;
float * s2 = sPool;
*s2 = 0.0f;
if(*s1 == 0) /* attempt to check binary interpretation of `0.0f' for equivalence to binary 0 */
{
/* do something */
}
Now such code as this example violates the "Strict Aliasing" rule.
Soma