Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[basic.life] It is unclear whether destroying an already destroyed scalar object is undefined behavior #361

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
frederick-vs-ja opened this issue Jul 13, 2023 · 6 comments

Comments

@frederick-vs-ja
Copy link

Full name of submitter (unless configured in github; will be published with the issue): Géry Ogam (cplusplus/draft#4944)

Reference (section label): [basic.life], [basic.start.term], [expr.prim.id.dtor], [expr.delete]

Link to reflector thread (if any):

Issue description:
P0593R6 made pseudo-destructor calls end lifetime of scalar objects. However, currently there lacks wording indicating that destroying an already destroyed scalar object is undefined behavior, which is inconsistent with class objects.

Currently, implementations tend to accept such double destruction in constant evaluation (Godbolt link). Note that Clang is inconsistent with itself, which seems to be a bug.

using I = int;
constexpr I x = (I{}.~I(), 0); // clang, gcc, and msvc accept this
constexpr I y = ((0).~I(), 0); // clang only rejects this

On the other hand, it is arguably better to keep and clarify the status quo, which avoids inceasing UB.

Suggested resolution:
The changes in cplusplus/draft#4953, if it is intented to make such double destruction undefined.

@sergey-anisimov-dev
Copy link

If you are referring to the (second) destruction happening automatically for the materialized temporary, it's an explicit issue only for the objects with non-trivial destructors. I'd say this is no different from a more simplified example:

{
  int i;
  i.~decltype(i)();
}

The above code is fine, since no non-trivial destructor for int exists. Clang indeed denies it constant-evaluation, though.

@frederick-vs-ja
Copy link
Author

If you are referring to the (second) destruction happening automatically for the materialized temporary, it's an explicit issue only for the objects with non-trivial destructors.

Yes. I think the status quo is that double destruction of int is well-defined.

However, it seems to me that [basic.life] p9 is nearly redundant, since [class.dtor] p18 covers almost all (if not all) of such cases. And [class.dtor] p18 states that UB happens even if the destructor is trivial - but pseudo-destructors are not covered.

@sergey-anisimov-dev
Copy link

Moreover, I'd say [class.dtor#18] itself is redundant in a normative sense. Basically, there are two substatements:

Once a destructor is invoked for an object, the object's lifetime ends

Already stated in [basic.life#1.4].

the behavior is undefined if the destructor is invoked for an object whose lifetime has ended

Already stated in [basic.life#6.2]/[basic.life#7.2], since destructors constitute non-static member functions.

@zygoloid
Copy link
Member

zygoloid commented Oct 9, 2024

This definitely seems unclear to me.

  • [basic.life]/4 and in general the fact that it seems meaningless to end the lifetime of an object whose lifetime has already ended suggests that destroying an out of lifetime object is always UB.
  • [basic.life]/7.2 suggests that destroying an object of class type that's out of lifetime is always UB, because it always invokes the destructor.
  • [basic.life]/10 suggests that it's UB to implicitly destroy an out of lifetime object (only) if it has a nontrivial destructor.

@zygoloid
Copy link
Member

zygoloid commented Oct 9, 2024

For what it's worth, in the context of P0593 I think the most logical thing would be to say that it's UB to destroy an out of lifetime object

@zygoloid
Copy link
Member

[diff.cpp17.basic]/1 also suggests that P0593 intended for this to be UB, but perhaps more wording cleanup is necessary to get us there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants