Влияет ли alignas на значение 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;
}

Вот код, дляalignas(double) unsigned char c[1024];это означаетc должны быть выровненыdouble,double является8 байт. Я так думаюsizeof(c) должно быть1024*8 байт, но вывод консоли1024.

Так что я в замешательстве. Кто может сказать мне причину?

 M.M10 авг. 2016 г., 23:50
как вы рисуете 1024 * 8? (выравнивание для начала массива, а не для каждого отдельного члена массива)

Ответы на вопрос(2)

Требование выравнивания влияет на весь объект, для которого оно указано, - в данном случае массив[1024] символа Таким образом, весь массив выравнивается до 8 байт, как будто он был сдвинут на несколько байт в памяти в целом, но его размер остается 1024 байт.

 Patrik H09 авг. 2016 г., 09:45
Группы отсутствуют, выравнивание влияет на то, в каких ячейках памяти может храниться переменная.Вот довольно много информации о том, что такое выравнивание памяти.
 BlackMamba09 авг. 2016 г., 09:31
Вы имеете в виду, что массивc выровнен по8 байт, просто означает каждый8 байты это группа.
Решение Вопроса

alignas Ключевое слово может быть использовано для определения требований выравнивания.alignas(double) например, заставляет переменную иметь те же требования выравнивания, что иdouble, На моей платформе это будет означать, что переменная выровнена по 8-байтовым границам.

В вашем примере весь массив получит требования к выравниванию, поэтому он выравнивается по 8-байтовым границам, но это не повлияет на его размер.

Однако возможно, чтоalignas изменяет размер составного типа данных, когда соблюдение требований выравнивания требует дополнительного заполнения. Вот пример:

#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;
}

Выход:

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

Размер этой структуры составляет 16 байт на моей платформе, хотя оба элемента имеют размер всего 1 байт каждый. Такb не стал больше из-за требования выравнивания, но послеa, Вы можете увидеть это, посмотрев на размер и смещение отдельных элементов.a всего 1 байт, ноb, в соответствии с нашими требованиями к выравниванию, начинается после 8-байтового смещения.

И размер структуры должен быть кратным ее выравниванию, иначе массивы не будут работать. Поэтому, если вы устанавливаете требование выравнивания, которое больше, чем должна была начинаться вся структура (например, структура, содержащая только одно короткое замыкание, и вы применяете alignas (double) к этому элементу данных), после него необходимо добавить заполнение.

 Steve Jessop09 авг. 2016 г., 14:59
И размер структуры должен быть кратным ее выравниванию, иначе массивы не будут работать. Таким образом, если вы устанавливаете требование выравнивания, которое больше, чем вся структура должна была начаться (например, структура, содержащая только одинshort и вы подаете заявкуalignas(double) к этому элементу данных), дополнение должно быть добавлено после него.
 Patrik H09 авг. 2016 г., 15:07
Спасибо Стив, это важный момент!

Ваш ответ на вопрос