Skip to content

CWG2986 [basic.life] Creating object within a mutable member subobject of a const complete object #367

Description

@frederick-vs-ja

Full name of submitter (unless configured in github; will be published with the issue): Jiang An

Reference (section label): [basic.life]

Link to reflector thread (if any):

Issue description:

Per [basic.life] p12, the following program has undefined behavior.

int main() {
  struct S {
    alignas(int) mutable unsigned char buf[sizeof(int)];
  };
  const S s{};
  ::new ((void*)s.buf) int{42};
}

Disallowing creating objects within a mutable member looks like an oversight, since it seemingly defeats the purpose of mutable.

We should also determine whether the behavior is well-defined if a union type has both mutable and non-mutable non-static data members, and an object is created within the mutable member of such a const complete union object.

Implementations accept the following code (Godbolt link), although it includes UB (per current rules) in constant evaluation.

constexpr bool test1() {
  union U {
    int x;
    mutable float y;
  };
  constexpr U u{.x = 42};
  u.y = 42.0f;
  return true;
}
static_assert(test1());

Suggested resolution:

Activity

  1. hubert-reinterpretcast commented on Jan 20, 2025

    @hubert-reinterpretcast
    Member

    @jensmaurer, I think some clarification here will help (to reinforce that we do mean UB for the non-mutable case).

  2. jensmaurer commented on Jan 20, 2025

    @jensmaurer
    Member

    @hubert-reinterpretcast , could you please add more detail which direction you want here?

    The link for the first example talk about "transparently replaceable" and re-using pointers. However, there are no pointers in sight here, so I'm confused. Maybe the link is stale.

    However, https://eel.is/c++draft/basic.life#12 has no carve-out for mutable subobjects, so this object creation is undefined behavior. Do you wish to have a carve-out for mutable subobjects here?

    Changing the active member of a const union seems a situation the standard doesn't talk about at all; should we forbid that?

  3. frederick-vs-ja commented on Jan 20, 2025

    @frederick-vs-ja
    Author

    The link for the first example talk about "transparently replaceable" and re-using pointers. However, there are no pointers in sight here, so I'm confused. Maybe the link is stale.

    Yeah. The paragraph used to be p10 but is now p12.

  4. hubert-reinterpretcast commented on Jan 20, 2025

    @hubert-reinterpretcast
    Member

    However, https://eel.is/c++draft/basic.life#12 has no carve-out for mutable subobjects, so this object creation is undefined behavior. Do you wish to have a carve-out for mutable subobjects here?

    Yes.

    Changing the active member of a const union seems a situation the standard doesn't talk about at all; should we forbid that?

    That technically is object creation (https://wg21.link/class.union.general#5), so it is already forbidden.

  5. jensmaurer commented on Jan 20, 2025

    @jensmaurer
    Member
  6. changed the title [-][basic.life] Creating object within a mutable member subobject of a const complete object[/-] [+]CWG2986 [basic.life] Creating object within a mutable member subobject of a const complete object[/+] on Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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