On Fri, Oct 02, 2015 at 02:07:32PM +0200, Paolo Bonzini wrote: > On 02/10/2015 13:14, Laszlo Ersek wrote: > > On 10/02/15 10:34, Paolo Bonzini wrote: > >> On 01/10/2015 21:17, Laszlo Ersek wrote: > >>> - In the firmware, allocate an array of bytes, dynamically. This array > >>> will have no declared type. > >>> > >>> - Populate the array byte-wise, from fw_cfg. Because the stores happen > >>> through character-typed lvalues, they do not "imbue" the target > >>> object with any effective type, for further accesses that do not > >>> modify the value. (I.e., for further reads.) > >>> > >>> - Get a (uint8_t*) into the array somewhere, and cast it to > >>> (struct acpi_table_hdr *). Read fields through the cast pointer. > >>> Assuming no out-of-bounds situation (considering the entire > >>> pointed to acpi_table_hdr struct), and assuming no alignment > >>> violations for the fields (which is implementation-defined), these > >>> accesses will be fine. > >>> > >>> *However*. If in point 2 you populate the array with uint64_t accesses, > >>> that *does* imbue the array elements with an effective type that is > >>> binding for further read accesses. > >> > >> Then don't do it. Use memcpy from uint64_t to the array. > > > > It won't work; memcpy() propagates the effective type. > > Doh. I guess that's another "not in practice" case. Saying "memcpy to > {,u}int8_t doesn't propagate the effective type" would probably go to > great lengths towards fixing this.
Just to be pedantic, uint8_t/int8_t are not the same as 'char' wrt aliasing rules. (The standard defines writes to a char array/pointer as being allowed to alias with other types, but does not say that about int8_t.) Gcc currently treats them as the same; I actually tried to get gcc to change that a few months ago: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66110#c13 FWIW, I think the aliasing rules allow for very useful optimizations and I wouldn't want to turn them off for programs where performance is important. The test case in the bug link above (which the gcc developers thankfully did address!) is a good example of the utility of alias detection. This function: void func(struct s2 *p) { p->p1->f2 = 9; p->p1->f2 = 10; } can't be optimized without -fstrict-aliasing. Indeed, even if the code was changed to p->p1->f3 = 11; p->p1->f4 = 12; then gcc would still need to reload p->p1 after every store. That's just silly. -Kevin