cplusplus / cplusplus/draft

[meta.const.eval] OptBool example and UB

Open
#8,780 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

P3-Other
Dominant language
TeX
Stars
221
Forks
813
Avg merge
16h 4m
Merged PRs (30d)
36

Description

The example for is_within_lifetime currently looks like this:

struct OptBool {
  union { bool b; char c; };

  // note: this assumes common implementation properties for bool and char:
  // * sizeof(bool) == sizeof(char), and
  // * the value representations for true and false are distinct
  //   from the value representation for 2
  constexpr OptBool() : c(2) { }
  constexpr OptBool(bool b) : b(b) { }

  constexpr auto has_value() const -> bool {
    if consteval {
      return std::is_within_lifetime(&b);       // during constant evaluation, cannot read from c
    } else {
      return c != 2;                            // during runtime, must read from c
    }
  }

  constexpr auto operator*() const -> const bool& {
    return b;
  }
};

There has been a lot of hand-wringing about this example recently, specifically about whether or not reading from c is undefined behavior if the active member of the union is actually b. Or, for a shorter example:

auto f() -> bool {
  union U { bool b; char c; };
  auto u = U{.b=true};
  return u.c != 2; // true or UB?
}

It's genuinely hard to tell from our wording whether or not this even is UB, but also it's besides the point of the example — which is that reading from c is definitely, explicitly disallowed during constant evaluation when b is the active member (in [expr.const]). So I think it'd be better to change the example from

return c != 2;

to

return bit_cast<char>(*this) != 2;

Which really should be unequivocally well-defined (and mean the same thing that I intended the original example to mean). With some suitable update to the comments.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Locate the [meta.const.eval] example for is_within_lifetime and review the related [expr.const] wording. Replace the runtime c comparison with the proposed bit_cast(*this) comparison and update the comments so the example no longer relies on reading c when b is active.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
documentation
Issue type
Documentation
Difficulty
1/5
Estimated time
Under an hour
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.