Szukaj…
Wprowadzenie
Wszystkie typy w C ++ mają wyrównanie. Jest to ograniczenie adresu pamięci, w którym mogą być tworzone obiekty tego typu. Adres pamięci jest ważny dla utworzenia obiektu, jeśli podzielenie tego adresu przez wyrównanie obiektu jest liczbą całkowitą.
Dopasowania typów są zawsze potęgą dwóch (w tym 1).
Uwagi
Standard gwarantuje:
- Wymaganiem wyrównania typu jest dzielnik jego wielkości. Na przykład klasa o rozmiarze 16 bajtów może mieć wyrównanie 1, 2, 4, 8 lub 16, ale nie 32. (Jeśli członkowie klasy mają tylko 14 bajtów, ale klasa musi mieć wymóg wyrównania z 8, kompilator wstawi 2 bajty wypełniające, aby rozmiar klasy był równy 16.)
- Podpisane i niepodpisane wersje typu liczb całkowitych mają takie same wymagania dotyczące wyrównania.
- Wskaźnik do
void
ma takie same wymagania wyrównania jak wskaźnik dochar
. - Wersje typu zakwalifikowane do CV i bez kwalifikacji do CV mają te same wymagania dotyczące wyrównania.
Zauważ, że chociaż wyrównanie istnieje w C ++ 03, dopiero w C ++ 11 stało się możliwe zapytanie o wyrównanie (za pomocą alignof
) i kontrolowanie wyrównania (za pomocą alignas
).
Zapytanie o wyrównanie typu
Wymagania dotyczące wyrównania typu można zapytać przy użyciu słowa kluczowego alignof
jako jednoargumentowego operatora. Wynik jest stałym wyrażeniem typu std::size_t
, tzn . Można go ocenić w czasie kompilacji.
#include <iostream>
int main() {
std::cout << "The alignment requirement of int is: " << alignof(int) << '\n';
}
Możliwe wyjście
Wymaganie wyrównania int to: 4
W przypadku zastosowania do tablicy daje wymóg wyrównania typu elementu. W przypadku zastosowania do typu odniesienia, daje to wymaganie wyrównania dla typu odniesienia. (Same odniesienia nie mają wyrównania, ponieważ nie są obiektami).
Kontrolowanie wyrównania
alignas
kluczowego alignas
można użyć do wymuszenia na zmiennej, elemencie danych klasy, deklaracji lub definicji klasy lub deklaracji lub definicji wyliczenia, aby uzyskać określone wyrównanie, jeśli jest obsługiwane. Występuje w dwóch formach:
-
alignas(x)
, gdziex
jest stałym wyrażeniem, nadaje jednostce wyrównaniex
, jeśli jest obsługiwane. -
alignas(T)
, gdzieT
jest typem, nadaje jednostce wyrównanie równe wymaganiu wyrównaniaT
, to znaczyalignof(T)
, jeśli jest obsługiwany.
Jeśli do tego samego obiektu zastosowano wiele specyfikatorów alignas
zastosowanie ma najściślejszy.
W tym przykładzie, bufor buf
zagwarantowane być odpowiednio dostosowane do utrzymywania się int
celu, chociaż jego typ elementu jest unsigned char
, które mają mniejszy wymaganie wyrównywania.
alignas(int) unsigned char buf[sizeof(int)];
new (buf) int(42);
alignas
nie można użyć do nadania typowi mniejszego wyrównania niż typ bez tej deklaracji:
alignas(1) int i; //Il-formed, unless `int` on this platform is aligned to 1 byte.
alignas(char) int j; //Il-formed, unless `int` has the same or smaller alignment than `char`.
alignas
, jeśli podano wyrażenie całkowite stałe, musi mieć prawidłowe wyrównanie. Prawidłowe wyrównania są zawsze potęgami dwóch i muszą być większe od zera. Kompilatory są wymagane do obsługi wszystkich poprawnych dopasowań do wyrównania typu std::max_align_t
. Mogą one obsługiwać większe niż wyrównania, ale poparcie dla przydzielania pamięci dla takich obiektów jest ograniczona. Górny limit wyrównania zależy od implementacji.
C ++ 17 oferuje bezpośrednią obsługę operator new
dla alokacji pamięci dla typów nadmiernie wyrównanych.