И они действительно 16 и 12.
Они имеют такой размер, учитывая:
- компилятор (и опции), который вы использовали
- ваша целевая платформа
- отсутствие директив, связанных с надписью / упаковкой в коде
Я полагаю, что для вашего видео спикер просто взял заданную платформу / набор инструментов для разработки своего примера. Однако в целом, поскольку sizeof(T)
зависит от компилятора / платформы, std::atomic<T>::is_lock_free()
также зависит от компилятора / платформы.
Примеры
Используя следующую структуру:
struct C {
uint64_t x;
uint32_t y;
};
Различные компиляторы и опции
Целевая платформа
Директивы по выравниванию / упаковке
Почему эти различия?
Компиляторы могут добавлять неиспользуемые биты / байты после любого поля структуры / класса. Они делают это по соображениям производительности: на некоторых платформах быстрее читать / записывать многобайтовый int
, который проверяет определенные свойства выравнивания (обычно адрес N
-байта int
должен делиться на N
).
Обычно удобно, чтобы ваш компилятор C ++ выполнял низкоуровневые оптимизации за вашей спиной. Иногда вам нужно больше контроля над этой функцией (неполный список причин):
- при сериализации данных, которые будут считаны другой программой (сохранить в файл, отправить в сеть).
- когда использование памяти важнее скорости выполнения.
- в многоядерной и многопоточной программе, управление количеством
struct
в строке кэша ЦП может ограничить аннулирования кэша между ядрами, что повышает скорость выполнения.
Именно поэтому компиляторы обычно предоставляют утилиты для управления им.
TL; DR
sizeof(T)
не "должен" быть чем-либо для данного T
. Это зависит от компилятора / платформы, и вы часто можете переопределить его с помощью специальных директив компилятора.