1

If we have a class which holds an array, let's call it vector and hold the values in a simple array called data:

class vector
{
public:
   double data[3];
   <...etc..>
};

Note: called as vector is for clearer explanation, it is not std::vector!!!

So my question is that, if I store only typedefs near this array inside the class and some constrexpr, am I correct if the class will be only 3 doubles after each other inside the memory? And then if i create an array of vectors like:

vector vl[3];

Note: size of the array is not always known at compile time, not use 3 for the example.

then in the memory it'll be just 9 doubles after each other, right? so vl[0].data[3] will always return the 2nd vectors 1st element? And in this case is it guaranteed that the result will be always like a simple array in the memory?

I found only cases with array of arrays, but not with array of classes holding an array, and I'm not sure if it is exactly the same at the end. I made some tests and it seems like it is working as I expected, but I don't know if it is always true.. Thank you!

2 Answers 2

2

Mostly, yes.

The standard doesn't promise that there never is anything after data in the representation of a vector, but all the implementations that I know of won't add any padding in this case.

What is promised is that there is no padding before data in the representation of vector, because it is a StandardLayout type.

Sign up to request clarification or add additional context in comments.

11 Comments

Thanks, so if I need an array of vectors, and element wise operations, it could be better in performance if i create a different class which will allocate a big chunk of memory (ie for 3 vectors, an array of 9 elements), and loop through that one? Since in this case everything is in a big contiguous block of memory without any extra padding for sure?
@simre it will likely be identical. Having one data member (an array is one thing) and nothing virtual is laid out with no padding by all the compilers I know of.
@simre As I said in my answer: You can simply static_assert the resulting struct size; if it is the sum of all member sizes then there is no padding. In general I'd try to use the natural data representation. If you have three vectors by all means use three vectors and not 9 unrelated numbers.
@Peter-ReinstateMonica, Yes but it is true only if you know the size at compile time. Sorry, I should have clarified that the size of the array is not always known at compile time. But I see in the link in your answer that the compiler can be "forced" to create a packed struct, so am I correct, if I use int, uint, float, or double for my vector data type, then the compiler won't add padding just put them right one after another? I'm using GCC so I can easily force it based on the linked answer. I try to avoid padding since my arrays can be already pretty big...
@simre you can't have a data member with an unknown size in C++. If you want runtime size, use std::vector
|
1

You are right with your first example: The class layout is like a C struct. The first member resides at the address of the struct itself, and if it is an array, all the array's members are adjacent.

Between struct members, however, may be padding; so there is no guarantee that the size of a struct is the sum of all member sizes. I'd have to dig into the standard but I assume this includes padding at the end. This answer affirms that; assert(sizeof(vector) == 3*sizeof(double)) may not hold. In reality I'd assume that an implementation may pad a struct containing three chars so that the struct aligns at word boundaries in an array, but not three doubles which are typically the type with the strongest alignment requirements. But there is no guarantee between implementations, architectures and compiler options: Imagine we switch to 128 bit CPUs.

With respect to your second example: The above applies recursively, so the standard gives no guarantee that the 9 doubles will be adjacent. On the other hand, I bet they will be, and the program can assert it with a simple compile-time static_assert.

3 Comments

vector in the question isn't std::vector, it's a mathematical 3-vector
Yes, sorry, I called it vector to be easier to understand.
@Caleth Oh sorry, I completely missed the class name ;-).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.