名前空間
変種
操作

C++ 属性: no_unique_address (C++20 以降)

From cppreference.com
< cpp‎ | language‎ | attributes
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 
属性
(C++23)
(C++11)(C++26 まで)
(C++14)
(C++20)
(C++17)
(C++11)
no_unique_address
(C++20)
(C++20)
 

このデータメンバが、そのクラスの他の非静的データメンバまたは基底クラスのサブオブジェクトと重複することを許可します。

目次

[編集] 構文

[[no_unique_address]]

[編集] 説明

ビットフィールドではない非静的データメンバの宣言で宣言されている名前に適用されます。

このメンバサブオブジェクトを潜在的に重複可能 (potentially-overlapping) にします。つまり、このメンバがそのクラスの他の非静的データメンバまたは基底クラスのサブオブジェクトと重複することを許可します。これは、メンバが空のクラス型 (例: ステートレスアロケータ) である場合、コンパイラが空の基底クラス (empty base) であるかのように、空間を占有しないように最適化できることを意味します。メンバが空でない場合、その中の末尾パディングも他のデータメンバを格納するために再利用される可能性があります。

[編集] 備考

MSVC では C++20 モードでも [[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 No unique address attribute [dcl.attr.nouniqueaddr]
  • C++20 standard (ISO/IEC 14882:2020)
  • 9.12.10 No unique address attribute [dcl.attr.nouniqueaddr]
English 日本語 中文(简体) 中文(繁體)