Given
template <typename T>
struct Vector3d { T x, y, z; };
Is it safe to assume that x, y, and z are in contiguous memory locations?
Is it at least safe to assume that for T = float
and T = double
?
If not is it possible to enforce in a cross-platform way?
Note: I don't mind padding after z as long as x, y, z are contigious
Is it safe to assume that x, y, and z are in contiguous memory locations?
There is technically no such guarantee by the language.
On the other hand, there is no need for them to not be contiguous either, and they are quite likely to be contiguous in practice.
If not is it possible to enforce in a cross-platform way?
The cross-platform way of having objects that are guaranteed to be in contiguous memory locations is an array:
template <typename T>
struct Vector3d { T components[3]; };
Arrays also make it legal to use pointer arithmetic to iterate over the objects.
Is it safe to assume that
x
,y
, andz
are in contiguous memory locations?
The standard doesn't make such a guarantee.
But in practice, a sane implementation isn't going to insert any padding between adjacent fields of the same type (since such padding is never necessary1).
If you want extra safety, add a static_assert
:
static_assert(sizeof(Vector3d<float>) == 3 * sizeof(float));
Is it at least safe to assume that for
T = float
andT = double
?
From what I know, field type doesn't make any difference here.
1 — Arrays are guaranteed to contain no padding. Since you can make an array of any type, implementation has to be able to store objects of any single type next to each other with no padding.
No there are absolutely no guarantees there is no padding between structure elements of the same types, even for "large" plain old data types such as a double
. Furthermore the behaviour on attempting to reach an element by pointer arithmetic on a pointer to another element is undefined.
Far better to write
template <typename T>
struct Vector3d { T t[3]; };
where contiguity and pointer arithmetic are guaranteed, and provide access functions for x
, y
, and z
.
If you don't like the syntax for calling functions, and are willing to tolerate some overhead that's most likely manifested in the struct
itself, then you could always bind references:
template <typename T>
struct Vector3d
{
T t[3];
T& x = t[0];
T& y = t[1];
T& z = t[2];
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With