TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.36K subscribers
Post #1030 4.12K
alignof
#опытным

Представим, что мы проектируем дизайн квартиры. Для того, чтобы расставлять предметы, нужно знать их размеры. Но не только это. Есть ещё одна важная характеристика — требования к размещению. Некоторые предметы можно ставить где угодно, другие требуют специального места у стены, третьи должны стоять строго в углу, четвертые прекрасно разместятся у вас в помойке за ненадобностью.

Чтобы дизайн получился хороший и все купленные предметы поместились и органично стояли на свои местах, нужно все эти требования знать.

С мебелью все просто - идешь и меряешь. Или смотришь размеры в онлайн магазине.

С данными так же, для них есть определенные требования к размеру и размещению. Но как их узнать?

Ну размер типа узнать просто - используем оператор sizeof, это все знают.

А требования к выравниваю как узнать?

Для этого есть C++11 оператор alignof. Он возвращает требуемое выравнивание для типа в байтах. Это значит, что адрес начала объекта данного типа был кратен результату alignof. Выравнивание должно быть степенью двойки(компьютеры у нас все-таки двоичные и все вокруг ее степени крутится).

В прошлом посте я голосновно перечислил выравнивания для базовых типов. Но теперь есть пруфы:

std::println("char требует выравнивания: {} байт", alignof(char));
std::println("short требует выравнивания: {} байт", alignof(short));
std::println("int требует выравнивания: {} байт", alignof(int));
std::println("size_t требует выравнивания: {} байт", alignof(size_t));
std::println("float требует выравнивания: {} байт", alignof(float));
std::println("double требует выравнивания: {} байт", alignof(double));
std::println("void* требует выравнивания: {} байт", alignof(void*));
// OUTPUT:
// char требует выравнивания: 1 байт
// short требует выравнивания: 2 байт
// int требует выравнивания: 4 байт
// size_t требует выравнивания: 8 байт
// float требует выравнивания: 4 байт
// double требует выравнивания: 8 байт
// void* требует выравнивания: 8 байт


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

std::println("std::string: размер={}, выравнивание={}", sizeof(std::string), alignof(std::string));
std::println("std::vector<int>: размер={}, выравнивание={}", sizeof(std::vector<int>), alignof(std::vector<int>));
// OUTPUT:
// std::string: размер=32, выравнивание=8
// std::vector<int>: размер=24, выравнивание=8


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

std::println("alignof(long double) = {}", alignof(long double));
std::println("alignof(std::max_align_t) = {}", alignof(std::max_align_t));
std::println("alignof(__m128) = {}", alignof(__m128));
// OUTPUT
// alignof(long double) = 16
// alignof(max_align_t) = 16
// alignof(__m128) = 16


double на самом деле не самую большую точность имеет из стандартных типов. Есть тип long double, его размер и выравнивание равны 16(на gcc и clang).

Также есть специальный тип std::max_align_t, чьи требования к выравниванию удовлетворяют любому скалярному типу. Тоже 16.

Для sse векторных регистров выравнивание тоже побольше.

Для чего этот оператор может применяться помимо учебных целей - рассмотрим в следующих постах.

Align yourself. Stay cool.

#cppcore #cpp11 #compiler
  • 👍 30
  • ❤ 11
  • 🔥 8
  • ⚡ 2
More from @grokaemcpp
  1. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  2. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  3. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  4. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  5. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
  6. Sep 25, 2026​​std::spanstream #опытным Радостная весть для всех, кто пользуется iostreams! В C++23 доб…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →