BlackMamba BlackMamba - 1 year ago 90
C++ Question

Does alignas affect the value of sizeof?

#include <iostream>
using namespace std;

int main()
{
alignas(double) unsigned char c[1024]; // array of characters, suitably aligned for doubles
alignas(16) char d[100]; // align on 16 byte boundary
cout<<sizeof(c)<<endl;
cout<<sizeof(d)<<endl;
constexpr int n = alignof(int); // ints are aligned on n byte boundarie
cout<<n<<endl;
}


Here is the code, for
alignas(double) unsigned char c[1024];
, it means the
c
should be aligned by
double
, the
double
is
8
bytes.
So I think
sizeof(c)
should be
1024*8
bytes, but the console output is
1024
.

So I am confused. Who can tell me the reason?

Answer Source

The alignas keyword can be used to dictate alignment requirements. alignas(double) for example forces the variable to have the same alignment requirements as a double. On my platform, this will mean that the variable is aligned on 8 byte boundaries.

In your example, the whole array will get the alignment requirements so it's being aligned on 8 byte boundaries but this won't affect its size.

It is however possible that alignas changes the size of a composite data type when upholding the alignment requirements requires additional padding. Here's an example:

#include <iostream>
#include <cstddef>

struct Test
{
    char a;
    alignas(double) char b;
};

int main(int argc, char* argv[])
{
    Test test;
    std::cout << "Size of Struct: " << sizeof(Test) << std::endl;
    std::cout << "Size of 'a': " << sizeof(test.a) << std::endl;
    std::cout << "Size of 'b': " << sizeof(test.b) << std::endl;
    std::cout << "Offset of 'a': " << (int)offsetof(struct Test, a) << std::endl;
    std::cout << "Offset of 'b': " << (int)offsetof(struct Test, b) << std::endl;
    return 0;
}

Output:

Size of Struct: 16
Size of 'a': 1
Size of 'b': 1
Offset of 'a': 0
Offset of 'b': 8

The size of this structure is 16 bytes on my platform even though both members are just 1 byte in size each. So b didn't become bigger because of the alignment requirement but there is additional padding after a. You can see this by looking at the size and offset of the individual members. a is just 1 byte in size but b, due to our alignment requirements, starts after a 8 byte offset.

And the size of a struct must be a multiple of its alignment, otherwise arrays don't work. So if you set an alignment requirement that's bigger than the whole struct was to begin with (for example a struct containing only a single short and you apply alignas(double) to that data member), padding must be added after it.