Yes, this will work on any compiler that follows the C99 standard. It will also probably work with compilers using earlier, less clear standards.
Here's why:
6.2.5.20 defines arrays as 'contiguously allocated' elements, while structs are 'sequentially allocated' members, and as long as all the struct members are the same type, this is really the same thing.
6.5.2.3 guarentees that if the types are used in a union visible currently, you can use things that are laid out in the same order transparently.
6.5 makes it clear that the 'effective type' for any access to an element of the array, or a field of the struct is 'float', so any two accesses may alias. An access to the struct as a whole is actually an access to each member in turn, so the same aliasing rules apply.
The 'union' requirement is most odd, but since types declared where a union is visible must be compatable with types defined identically in another compilation unit without the union, the same rules end up applying even where the union is not visible.
Edit
The key point here is the distinction between things that are undefined vs things that are implementation defined. For undefined things, the compiler might to anything, and might do different things when recompiling the same source file. For implementation defined things, you might not know exactly what it does, but it must do the same thing consistently across compilation units. So even where the spec doesn't exactly spell out how something must be done, the interaction between different things and the fact that things must be consistent across compilation units with compatable type declarations greatly restricts what the compiler can do here.