C++ attribute: no_unique_address (since C++20)
| General topics | ||||||||||||||||
| Flow control | ||||||||||||||||
| Conditional execution statements | ||||||||||||||||
| Iteration statements (loops) | ||||||||||||||||
|
||||||||||||||||
| Jump statements | ||||||||||||||||
| Functions | ||||||||||||||||
| Function declaration | ||||||||||||||||
| Lambda function expression | ||||||||||||||||
inline
specifier
|
||||||||||||||||
| Dynamic exception specifications ( until C++17* ) | ||||||||||||||||
noexcept
specifier
(C++11)
|
||||||||||||||||
| Exceptions | ||||||||||||||||
| Namespaces | ||||||||||||||||
| Types | ||||||||||||||||
| Specifiers | ||||||||||||||||
|
||||||||||||||||
| Storage duration specifiers | ||||||||||||||||
| Initialization | ||||||||||||||||
| Expressions | ||||||||||||||||
| Alternative representations | ||||||||||||||||
| Literals | ||||||||||||||||
| Boolean - Integer - Floating-point | ||||||||||||||||
| Character - String - nullptr (C++11) | ||||||||||||||||
| User-defined (C++11) | ||||||||||||||||
| Utilities | ||||||||||||||||
| Attributes (C++11) | ||||||||||||||||
| Types | ||||||||||||||||
typedef
declaration
|
||||||||||||||||
| Type alias declaration (C++11) | ||||||||||||||||
| Casts | ||||||||||||||||
| Memory allocation | ||||||||||||||||
| Classes | ||||||||||||||||
| Class-specific function properties | ||||||||||||||||
|
||||||||||||||||
| Special member functions | ||||||||||||||||
|
||||||||||||||||
| Templates | ||||||||||||||||
| Miscellaneous | ||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
(C++23)
|
||||
|
(C++11)
(until C++26)
|
||||
|
(C++14)
|
||||
|
(C++17)
|
||||
|
(C++26)
|
||||
|
(C++20)
|
||||
|
(C++17)
|
||||
|
(C++17)
|
||||
|
(C++11)
|
||||
|
no_unique_address
(C++20)
|
||||
|
(TM TS)
|
||||
|
(C++20)
|
Permet à ce membre de données d'être superposé avec d'autres membres de données non statiques ou sous-objets de classe de base de sa classe.
Table des matières |
Syntaxe
[
[
no_unique_address
]
]
|
|||||||||
Explication
S'applique au nom déclaré dans la déclaration d'un membre de données non statique qui n'est pas un champ de bits.
Rend ce sous-objet membre potentiellement chevauchant , c'est-à-dire permet à ce membre d'être chevauché avec d'autres membres de données non statiques ou sous-objets de classe de base de sa classe. Cela signifie que si le membre a un type de classe vide (par exemple un allocateur sans état), le compilateur peut l'optimiser pour qu'il n'occupe aucun espace, tout comme s'il s'agissait d'une base vide . Si le membre n'est pas vide, tout remplissage de fin dans celui-ci peut également être réutilisé pour stocker d'autres membres de données.
Notes
[ [ no_unique_address ] ] est ignoré par MSVC même en mode C++20 ; à la place, [ [ msvc :: no_unique_address ] ] est fourni.
Exemple
#include <boost/type_index.hpp> #include <iostream> struct Empty {}; // La taille de tout objet de type classe vide est au moins 1 static_assert(sizeof(Empty) >= 1); struct X { int i; Empty e; // Au moins un octet supplémentaire est nécessaire pour donner à 'e' une adresse unique }; static_assert(sizeof(X) >= sizeof(int) + 1); struct Y { int i; [[no_unique_address]] Empty e; // Membre vide optimisé }; static_assert(sizeof(Y) >= sizeof(int)); struct Z { char c; // e1 et e2 ne peuvent pas partager la même adresse car ils ont le // même type, même s'ils sont marqués avec [[no_unique_address]]. // Cependant, chacun peut partager l'adresse avec 'c'. [[no_unique_address]] Empty e1, e2; }; static_assert(sizeof(Z) >= 2); struct W { char c[2]; // e1 et e2 ne peuvent pas avoir la même adresse, mais l'un // d'eux peut partager avec c[0] et l'autre avec c[1] : [[no_unique_address]] Empty e1, e2; }; static_assert(sizeof(W) >= 2); template <typename T> void print_size_of() { using boost::typeindex::type_id; std::cout << "sizeof(" << type_id<T>() << ") == " << sizeof(T) << '\n'; } int main() { print_size_of<Empty>(); print_size_of<int>(); print_size_of<X>(); print_size_of<Y>(); print_size_of<Z>(); print_size_of<W>(); }
Sortie possible :
sizeof(Empty) == 1 sizeof(int) == 4 sizeof(X) == 8 sizeof(Y) == 4 sizeof(Z) == 2 sizeof(W) == 3
Références
- Norme C++23 (ISO/CEI 14882:2024) :
-
- 9.12.11 Attribut d'absence d'adresse unique [dcl.attr.nouniqueaddr]
- Norme C++20 (ISO/CEI 14882:2020) :
-
- 9.12.10 Attribut d'absence d'adresse unique [dcl.attr.nouniqueaddr]