Is this code well-defined behavior, in terms of strict aliasing?
_Bool* array = malloc(n);
memset(array, 0xFF, n);
_Bool x = array[0];
The rule of effective type has special cases for memcpy
and memmove
(C17 6.5 §6) but not for memset
.
My take is that the effective type becomes unsigned char
. Because the second parameter of memset
is required to be converted to unsigned char
(C17 7.24.6.1) and because of the rule of effective type, (C17 6.5 §6):
...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.
- Question 1: What is the effective type of the data stored in
array
after thememset
call? - Question 2: Does the
array[0]
access therefore violate strict aliasing? Since_Bool
is not a type excluded from the strict aliasing rule (unlike character types).
memset
does not change the effective type. C11 (C17) 6.5p6:Since the values are stored with an
lvalue
that has character type insidememset
, and not have the bytes copied from another object with lvalues of character type (the clause exists to equatememcpy
andmemmove
with doing the same with an explicitfor
loop!), it does not get an effective type, and the effective type of elements is_Bool
for those accessed througharray
.There might be parts in the C17 standard that are underspecified, but this certainly is not one of those cases.
array[0]
would not violate the effective type rule.That does not make using the value of
array[0]
any more legal. It can (and will most probably) be a trap value!I tried the following functions
with
array[0]
as any of the arguments - for the sake of avoiding compile-time optimizations this was compiled separately. When compiled with -O3 the following messages were printed:And when without any optimization