Daily bit(e) C++. [[no_unique_address]]

Добавлено 30 сентября 2026 в 17:24

Daily bit(e) C++ 129, атрибут члена класса [[no_unique_address]] из стандарта C++20.

Daily bit(e) C++

В стандарте C++20 появился атрибут [[no_unique_address]], который можно использовать для аннотирования нестатических членов данных.

Этот атрибут позволяет компилятору оптимизировать пустые члены класса, помеченные данным атрибутом, так, чтобы они не занимали места в памяти.

#include <utility>

struct Empty {};

struct Bigger 
{
    int value;
    // Даже пустой, он должен занимать как минимум один байт.
    Empty empty;
};

struct SameAsInt 
{
    int value;
    // Допускается перекрытие.
    [[no_unique_address]] Empty empty;
};

int main() 
{
    static_assert(sizeof(Empty) >= 1);
    static_assert(sizeof(Bigger) >= sizeof(int) + 1);
    static_assert(sizeof(SameAsInt) == sizeof(int));
}

Пример на Compiler Explorer

На практике этот атрибут очень полезен для шаблонов. Например,

template<class T, class Deleter>
struct Pointer 
{
    T* ptr;
    Deleter deleter;
};

Если Deleter – пустой stateless-класс

struct DefaultDeleter {};

то без [[no_unique_address]] Pointer<int, DefaultDeleter> может занимать больше места, чем один указатель.

С [[no_unique_address]], можно написать:

template<class T, class Deleter>
struct Pointer 
{
    T* ptr;
    [[no_unique_address]] Deleter deleter;
};

Теперь пустой Deleter может занимать нулевой дополнительный размер.

Теги

C++ / CppDaily bit(e) C++Программирование