命名空间
变体
操作

C++ 属性: no_unique_address (自 C++20 起)

来自 cppreference.cn
< cpp‎ | language‎ | attributes
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句 (循环)
for
范围 for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (直到 C++17* 才弃用)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
 
 
属性
(C++23)
(C++11)(直到 C++26)
(C++14)
(C++20)
(C++17)
(C++11)
no_unique_address
(C++20)
(C++20)
 

允许此数据成员与其类的其他非静态数据成员或基类子对象重叠。

目录

[编辑] 语法

[[no_unique_address]]

[编辑] 解释

应用于非静态数据成员声明中声明的名称,该成员不是位字段。

使此成员子对象成为潜在重叠,即允许此成员与其类的其他非静态数据成员或基类子对象重叠。这意味着如果成员具有空类类型(例如,无状态分配器),编译器可以优化它以不占用空间,就像它是空基类优化一样。如果成员不为空,则其中的任何尾部填充也可能被重用以存储其他数据成员。

[编辑] 注意

[[no_unique_address]] 在 MSVC 中即使在 C++20 模式下也会被忽略;相反,提供了 [[msvc::no_unique_address]]

[编辑] 示例

#include <iostream>
 
struct Empty {}; // empty class
 
struct X
{
    int i;
    Empty e;
};
 
struct Y
{
    int i;
    [[no_unique_address]] Empty e;
};
 
struct Z
{
    char c;
    [[no_unique_address]] Empty e1, e2;
};
 
struct W
{
    char c[2];
    [[no_unique_address]] Empty e1, e2;
};
 
int main()
{
    // the size of any object of empty class type is at least 1
    static_assert(sizeof(Empty) >= 1);
 
    // at least one more byte is needed to give e a unique address
    static_assert(sizeof(X) >= sizeof(int) + 1);
 
    // empty member optimized out
    std::cout << "sizeof(Y) == sizeof(int) is " << std::boolalpha 
              << (sizeof(Y) == sizeof(int)) << '\n';
 
    // e1 and e2 cannot share the same address because they have the
    // same type, even though they are marked with [[no_unique_address]]. 
    // However, either may share address with c.
    static_assert(sizeof(Z) >= 2);
 
    // e1 and e2 cannot have the same address, but one of them can share with
    // c[0] and the other with c[1]
    std::cout << "sizeof(W) == 2 is " << (sizeof(W) == 2) << '\n';
}

可能的输出

sizeof(Y) == sizeof(int) is true
sizeof(W) == 2 is true

[编辑] 参考

  • C++23 标准 (ISO/IEC 14882:2024)
  • 9.12.11 No unique address attribute [dcl.attr.nouniqueaddr]
  • C++20 标准 (ISO/IEC 14882:2020)
  • 9.12.10 No unique address attribute [dcl.attr.nouniqueaddr]