Ricerca…


introduzione

Tutti i tipi in C ++ hanno un allineamento. Questa è una restrizione sull'indirizzo di memoria che gli oggetti di quel tipo possono essere creati all'interno. Un indirizzo di memoria è valido per la creazione di un oggetto se la divisione di quell'indirizzo tramite l'allineamento dell'oggetto è un numero intero.

Gli allineamenti di tipo sono sempre una potenza di due (incluso 1).

Osservazioni

Lo standard garantisce quanto segue:

  • Il requisito di allineamento di un tipo è un divisore delle sue dimensioni. Ad esempio, una classe con dimensione 16 byte potrebbe avere un allineamento di 1, 2, 4, 8 o 16, ma non 32. (Se i membri di una classe hanno solo 14 byte di dimensione, la classe deve avere un requisito di allineamento di 8, il compilatore inserirà 2 byte di riempimento per rendere la dimensione della classe uguale a 16.)
  • Le versioni firmate e non firmate di un tipo intero hanno lo stesso requisito di allineamento.
  • Un puntatore a void ha lo stesso requisito di allineamento di un puntatore al char .
  • Le versioni cv-qualificate e cv-non qualificate di un tipo hanno lo stesso requisito di allineamento.

Si noti che mentre l'allineamento esiste in C ++ 03, non è stato fino a C ++ 11 che è diventato possibile interrogare l'allineamento (usando alignof ) e l'allineamento di controllo (usando alignas ).

Interrogare l'allineamento di un tipo

c ++ 11

Il requisito di allineamento di un tipo può essere interrogato utilizzando la parola chiave alignof come operatore unario. Il risultato è un'espressione costante di tipo std::size_t , cioè può essere valutata in fase di compilazione.

#include <iostream>
int main() {
    std::cout << "The alignment requirement of int is: " << alignof(int) << '\n';
}

Uscita possibile

Il requisito di allineamento di int è: 4

Se applicato a un array, restituisce il requisito di allineamento del tipo di elemento. Se applicato a un tipo di riferimento, restituisce il requisito di allineamento del tipo di riferimento. (I riferimenti stessi non hanno allineamento, dal momento che non sono oggetti.)

Controllo dell'allineamento

C ++ 11

La parola chiave alignas può essere utilizzata per forzare una variabile, un membro di dati di classe, una dichiarazione o definizione di una classe, o una dichiarazione o una definizione di enum, per avere un particolare allineamento, se supportato. Si presenta in due forme:

  • alignas(x) , dove x è un'espressione costante, dà all'entità l'allineamento x , se supportato.
  • alignas(T) , dove T è un tipo, dà all'entità un allineamento uguale al requisito di allineamento di T , cioè alignof(T) , se supportato.

Se più alignas sono applicati alla stessa entità, si applica la più severa.

In questo esempio, è garantito che il buffer buf sia allineato in modo appropriato per contenere un oggetto int , anche se il suo tipo di elemento è unsigned char , che potrebbe avere un requisito di allineamento più debole.

alignas(int) unsigned char buf[sizeof(int)];
new (buf) int(42);

alignas non può essere usato per dare a un tipo un allineamento più piccolo di quello che avrebbe il tipo senza questa dichiarazione:

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 , quando viene fornita un'espressione costante intera, devono avere un allineamento valido. Gli allineamenti validi sono sempre poteri di due e devono essere maggiori di zero. I compilatori sono tenuti a supportare tutti gli allineamenti validi fino all'allineamento del tipo std::max_align_t . Possono supportano allineamenti grandi di questo, ma il supporto per l'allocazione di memoria per tali oggetti è limitata. Il limite superiore per gli allineamenti dipende dall'implementazione.

C ++ 17 offre un supporto diretto per l' operator new per l'allocazione della memoria per i tipi sovradimensionati.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow