Skip to content

Layout compatible classes involving [[no_unique_address]] #108

Closed
@leni536

Description

@leni536

Consider the following example:

#include <type_traits>
#include <cstddef>

class A1 {
    private:
    int i;
    char ch;
};

class B1 {
    public:
    [[no_unique_address]] A1 a;
    char ch;
};

static_assert(std::is_standard_layout_v<B1>);

class A2 {
    public:
    int i;
    char ch;
};

class B2 {
    public:
    [[no_unique_address]] A2 b2;
    char ch;
};

static_assert(std::is_standard_layout_v<B1>);
static_assert(offsetof(B1, ch) != offsetof(B2, ch));

Godbolt: https://godbolt.org/z/1o91bE

Following the standard wording A1 and A2 are layout compatible [1]. Similarly B1 and B2 are layout compatible. However the ch member in B1 has different offset than the ch member in B2.

A1 is not POD for the purpose of layout while A2 is, this affects the offset of the ch member.

Two possible directions to fix this:

  1. Modify the standard to disallow [[no_unique_address]] non-empty non-static data members to be part of a common initial sequence (or maybe only allow as the last element of a common initial sequence).
  2. Modify the ABI to disable overlapping of [[no_unique_address]] non-empty data members in standard-layout classes.

Personally I would prefer the first option of these two.

[1] https://eel.is/c++draft/class#mem.general-22

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions