Code 1:
unsigned int *p = malloc(sizeof *p);
memset(p, 0x55, sizeof *p);
unsigned int u = *p;
Code 2:
void *d = malloc(50);
*(double *)d = 1.23;
memset(d, 0x55, 50);
unsigned int u = *(unsigned int *)d;
In each case, what effect does memset
have on the effective type of the object in the malloc'd space; and so is initializing u
correct or a strict aliasing violation?
The definition of effective type (C11 6.5/6) is:
The effective type of an object for an access to its stored value is the declared type of the object, if any. If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. If a value is copied into an object having no declared type using
memcpy
ormemmove
, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.
However it is unclear whether memset
behaves like writing through an lvalue of character type, or something else. The description of memset
(7.24.6.1) is not very illuminating:
The memset function copies the value of c (converted to an
unsigned char
) into each of the first n characters of the object pointed to by s.
calloc
is even vaguer on this point - "The space is initialized to all bits zero. [footnote] Note that this need not be the same as the representation of floating-point zero or a null pointer constant." – Schaaffmemset
andcalloc
were intended to behave as-if they access storage through an lvalue of character type; indeed, I think the wording in 6.5/6 for "If a value is stored into an object having no declared type through an lvalue having a type that is not a character type" is intended precisely to permit erasing heap blocks withmemset
andcalloc
. I am, now, less convinced that the standard actually specifies what it was meant to re these functions, than I was when I wrote the "related question". – Schaaff*(T *)p = t;
, then the block has effective typeT
– Hairlessmemset
. – Schaaffmemset
, does that then render the whole object unreadable by what its effective type was before? – Hairlessdouble
after thememset
. :-( – Schaaffmemset(void *s, ...)
takes one type of object for the destination: avoid*
. It "copies the value of c ... into each of the first n characters of the object pointed to by s". Thus effectively,memset()
treats the pointer as a character pointer. Certain all this is well know to you. But not clear why it is insufficient to answer "What is the effective type of an object written by memset?". – Sangria