Code 1:
unsigned int *p = malloc(sizeof *p);
memset(p, 0x55, sizeof *p);
unsigned int u = *p;
Code 2:
void *d = malloc(50)
My 50ct:
First, I break this into sentences for easier reference:
The footnote might help here: "87) Allocated objects have no declared type.".
DNA: "does not apply"
Case 1:
memset(...): 1: DNA (no declared type), 2: DNA (memset writes to char - semantics), 3: DNA (neither memcpy nor memmove), 4: char [] for memset internally only (not permanent).unsigned int u = *p: 1: DNA (no declared type), 2/3: DNA (no write, but read), 4: type of lvalue is unsigned int.Conclusion: no violation, but the interpretion is implementation defined, as the actual value depends on alignment within the variable and endianess.
Case 2:
*(double *)d = 1.23;: 2: d becomes double * for this and following reads.memset(d, 0x55, 50);: same as for Case 1.unsigned int u = *(unsigned int *)d: d is still double *: bang!In any way, memset() is of litte use for non-char scalars, except if using 0, which is still implementation dependent, as neither (float)0.0, nor the null pointer need to be actually "all bits zero".
Finally:
memset, as internally, memset() copies by char: "...of c (converted to an unsigned char) into each of the first n characters ..." (or uses char semantics, at least; the actual implementation is irrelevant here).memset(), either, as that only applies to memcpy/memmove or when copying as "an array of character type". Which it also does not (but the former do, so the or-condition just makes an explicit copy-loop equivalent to the functions).memset() does not change the effective type of the object. That differs from memcpy and memmove. That results from sentence 4, which does not include "... for that access and for subsequent accesses ..." as 2 and 3 state and 1 implies.Hope that helps. Constructive criticism welcome.