I just had a look into the crates simd and simdty and wondered why they had chosen to use tupels like that:
struct u32x4(u32, u32, u32, u32);
Wouldn't a newtype or type alias like
struct u32x4([u32; 4]);
or
type u32x4 = [u32; 4];
be more convenient? You could use indexing, transmuting, iterating, slicing, whatever. And - AFAIK - the internal representation is clearly defined (is it?). Or are there simd types with mixed content?
Edit: as @sfackler pointed out, a type alias wouldn't allow alignment rules solely for the usage as a simd type.
I assume indexing an array (as opposed to a slice) does not have runtime bounds checks either when using constant indices? The compiler certainly has all the information it needs not to generate a compile-time check.
warning: this expression will panic at run-time
--> src/lib.rs:11:20
|
11 | println!("{}", foo.0[4]);
| ^^^^^^^^ index out of bounds: the len is 4 but the index is 4
Half of it is backwards compatibility (since these warnings do not
exist in a vacuum, but rather arise from optimizations), and the other
half is that code being objectively bad is not a certainty without
potentially unbounded context.
Could you elaborate on this? I know type aliases are just syntactic sugar, but what prevents us from defining simd-operations on [u32; 4]?
Not to be misunderstood: I currently consider the newtype to be the cleaner solution. Overloaded operators wouldn't collide with other use cases (like: is [1, 2, 3] + [4, 5, 6] an addition or a concatenation?).
SIMD types have different alignment requirements than normal arrays - loads that aren't aligned to 16 bytes will fault. Calling conventions also differ I believe.