yohhoyの日記

技術的メモをしていきたい日記

アクセス制御とメンバ変数メモリレイアウト

プログラミング言語C++が定義する POD(plain old data)型 において、該当POD型のメンバ変数がメモリ上にどのような順序で配置されるか(メモリレイアウト)と、メンバのアクセス制御(public/privateなど)の関係についてメモ。

まとめ*1

  • POD型の各メンバ変数に対応するメモリ位置は、ソースコード上の宣言順序にて配置されると保証される。(5.9/p2)
  • C++03:POD型は aggregate(集成体) であること。メンバ変数が全てpublicアクセス制御であること。*2
  • C++11:POD型は standard-layout class であること。全メンバ変数が同じアクセス制御であればよい。(例:全てprivateなど)

2021-06-22追記:C++2b(C++23)で採択予定の(PDF)P1847R4では、メンバ変数のアクセス制御によらず記述順で配置されるようになる。またC++20以降では用語PODが非推奨となり、trivial type と standard-layout class に概念分割された。

注意:C++標準規格が定めるのは “メンバ変数メモリ位置の順序” だけであり、メンバ変数間の距離(パディング)については処理系依存。このパディング量は#pragmaやコンパイルオプションなどで明示する必要がある。

C++03

C++03 5.9/p2, 8.5.1/p1, 9/p4より一部引用(下線部は強調)。

2 (snip) Pointers to objects or functions of the same type (after pointer conversions) can be compared, with a result defined as follows:

  • (snip)
  • If two pointers point to nonstatic data members of the same object, or to subobjects or array elements of such members, recursively, the pointer to the later declared member compares greater provided the two members are not separated by an access-specifier label (11.1) and provided their class is not a union.
  • If two pointers point to nonstatic data members of the same object separated by an access-specifier label (11.1) the result is unspecified
  • (snip)

1 An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).

4 (snip) [Note: aggregates of class type are described in 8.5.1.] A POD-struct is an aggregate class that has ...(snip)

C++11

N3337 5.9/p2, 9/p7, p10より一部引用(下線部は強調)。

2 (snip) Pointers to objects or functions of the same type (after pointer conversions) can be compared, with a result defined as follows:

  • (snip)
  • If two pointers point to non-static data members of the same object, or to subobjects or array elements of such members, recursively, the pointer to the later declared member compares greater provided the two members have the same access control (Clause 11) and provided their class is not a union.
  • If two pointers point to non-static data members of the same object with different access control (Clause 11) the result is unspecified
  • (snip)

7 A standard-layout class is a class that:

  • (snip)
  • has the same access control (Clause 11) for all non-static data members,
  • (snip)

10 A POD struct is a non-union class that is both a trivial class and a standard-layout class, ...(snip)

関連URL

*1:ここでは “非staticな” メンバ変数のみを考慮する。

*2:C++03 5.9/p2に厳密に従うと、struct X { int m1; public: int m2; }; は m1, m2 間の順序保証が無くなる。