Date: Mon, 31 Jul 2023 19:09:32 -0700
On Monday, 31 July 2023 16:52:40 PDT Jason McKesson via Std-Discussion wrote:
> > unless the compiler can prove that get_pointer_x1() did not create an
> > object of type U there.
>
> That's not how UB works. It's not defined on the basis of what the
> compiler can "prove" happened. It's defined by what *actually
> happens*. `get_pointer_x1` did something. If that something was to
> create an object of type `U`, then this behavior may be defined.
> Otherwise it is not.
>
> This isn't about what people can expect to get away with from their
> compilers. This is about what's actually going on in the object model.
> What `get_pointer_x1` actually does is part of that.
That's a fair point, but in practical terms it has no effect. That's why I was
arguing about what the compiler can use. I don't think pedantism in the
language for something that can't be used in practice case is useful.
Even looking at what actually happens, I am arguing that the majority of
functions where these standard library special functions would be needed,
objects *were* created of such types, because either
a) you end up in a malloc() or memcpy() somewhere
or
b) you cross into another language (usually C) where the rules of lifetime
start that apply are different
The C++ *standard* may not say what happens when you cross to another language
and thus the discussion would be out-of-scope for this mailing list, but I
think it should be in scope. The C++ *compilers* do support and must continue
to support interoperating with C code. Therefore, I am arguing the *standard*
must acknowledge this existential requirement for the C++ ecosystem and
properly bless and standardise interaction with C libraries and OSes;
With that done, the vast majority of needs for std::start_lifetime_as go the
way of the dodo. I am actually hard pressed to come up with any:
std::construct_at + std::launder / reinterpret_cast should suffice.
I'll go further and say that once you accept that C started lifetimes for
those objects, then std::start_lifetime_as is actually wrong, because you'd be
restarting the lifetime. Unless std::start_lifetime_as is defined as
idempotent, but if so then why are it and std::launder distinct?
> > unless the compiler can prove that get_pointer_x1() did not create an
> > object of type U there.
>
> That's not how UB works. It's not defined on the basis of what the
> compiler can "prove" happened. It's defined by what *actually
> happens*. `get_pointer_x1` did something. If that something was to
> create an object of type `U`, then this behavior may be defined.
> Otherwise it is not.
>
> This isn't about what people can expect to get away with from their
> compilers. This is about what's actually going on in the object model.
> What `get_pointer_x1` actually does is part of that.
That's a fair point, but in practical terms it has no effect. That's why I was
arguing about what the compiler can use. I don't think pedantism in the
language for something that can't be used in practice case is useful.
Even looking at what actually happens, I am arguing that the majority of
functions where these standard library special functions would be needed,
objects *were* created of such types, because either
a) you end up in a malloc() or memcpy() somewhere
or
b) you cross into another language (usually C) where the rules of lifetime
start that apply are different
The C++ *standard* may not say what happens when you cross to another language
and thus the discussion would be out-of-scope for this mailing list, but I
think it should be in scope. The C++ *compilers* do support and must continue
to support interoperating with C code. Therefore, I am arguing the *standard*
must acknowledge this existential requirement for the C++ ecosystem and
properly bless and standardise interaction with C libraries and OSes;
With that done, the vast majority of needs for std::start_lifetime_as go the
way of the dodo. I am actually hard pressed to come up with any:
std::construct_at + std::launder / reinterpret_cast should suffice.
I'll go further and say that once you accept that C started lifetimes for
those objects, then std::start_lifetime_as is actually wrong, because you'd be
restarting the lifetime. Unless std::start_lifetime_as is defined as
idempotent, but if so then why are it and std::launder distinct?
-- Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org Software Architect - Intel DCAI Cloud Engineering
Received on 2023-08-01 02:09:35