名稱空間
變體
操作

C++ 屬性: no_unique_address (C++20 起)

來自 cppreference.com
< cpp‎ | 語言‎ | 屬性
 
 
C++ 語言
 
 
屬性
(C++23)
(C++11)(直至 C++26)
(C++14)
(C++20)
(C++17)
(C++11)
no_unique_address
(C++20)
(C++20)
 

允許此資料成員與其類的其他非靜態資料成員或基類子物件重疊。

目錄

[編輯] 語法

[[no_unique_address]]

[編輯] 解釋

應用於非位域的非靜態資料成員宣告中宣告的名稱。

使此成員子物件可能重疊,即允許此成員與其類的其他非靜態資料成員或基類子物件重疊。這意味著如果該成員具有空類型別(例如無狀態分配器),編譯器可以對其進行最佳化以不佔用任何空間,就像它是一個空基類一樣。如果該成員不為空,則其任何尾部填充也可以重複使用以儲存其他資料成員。

[編輯] 注意

即使在 C++20 模式下,MSVC 也忽略 [[no_unique_address]];而是提供 [[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 無唯一地址屬性 [dcl.attr.nouniqueaddr]
  • C++20 標準 (ISO/IEC 14882:2020)
  • 9.12.10 無唯一地址屬性 [dcl.attr.nouniqueaddr]