Date: Sun, 2 Oct 2022 10:32:25 -0400
On Sun, Oct 2, 2022 at 8:20 AM blacktea hamburger via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>>
>> UB is bad when it's *inconsistent*. Making it so that your
>> creation/allocation and destruction/deallocation have to match is
>> consistent. Making it so that inconsistent code sometimes works
>> doesn't make the language easier to learn. It just adds complexity in
>> the name of... what, exactly?
>
>
>
> Not. It is still not recommended (but sometimes it is really needed), but if someone really does it, it should not be UB.
>
>
>> Can you give a reason why such a rule ought not be followed? Show me
>> actual good code that doesn't follow this rule. Not just code that
>> technically works because of some statement in the bowels of the
>> standard, but code that has some kind of advantage that is arguably
>> more important than having a simple rule everyone understands and can
>> easily follow.
>
>
> In fact, it is very simple, when the storage to be allocated is larger than the object occupies. inlined_fixed_string in P0722R1 is an example, It uses new (::operator new(full_size)) inlined_fixed_string(data.size(), data.c_str()) to allocate and delete-expression can be used to deallocate.
That's... actually a pretty good example. Though it should be noted
how tied into a specific type it is, and the asymmetry of the
creation/destruction of the object (using a `Make` function, but
`delete` for destruction) is unsightly. I would have used an explicit
`Destroy` function, or better yet, returned a `unique_ptr`, but
whatever.
That being said... how does this apply to IOC? The above code is very
C++, using non-trivial constructors to create the object.
`inlined_fixed_string` is not an implicit lifetime type.
I mean sure, you could take everything out of the constructor and
stick it in `Make` and pretend to make it work. But why would you
*have to*?
Remember: IOC is largely a compatibility feature. It's for code that
needs to work in C and C++, as well as a few edge cases such as
loading from files and the like. But `inline_fixed_string` needs C++;
it has member functions and an `operator delete` overload. It is
categorically not a C API. So why would you rely on IOC when you can
use C++ features directly and much more naturally?
Even if you were #ifdef'ing around the C++ to make it compile as C,
you could just #ifdef around the `new(p) inline_fixed_string` part in
`Make`.
So there's no reason why you would specifically need IOC to play along
with such gymnastics.
<std-proposals_at_[hidden]> wrote:
>>
>> UB is bad when it's *inconsistent*. Making it so that your
>> creation/allocation and destruction/deallocation have to match is
>> consistent. Making it so that inconsistent code sometimes works
>> doesn't make the language easier to learn. It just adds complexity in
>> the name of... what, exactly?
>
>
>
> Not. It is still not recommended (but sometimes it is really needed), but if someone really does it, it should not be UB.
>
>
>> Can you give a reason why such a rule ought not be followed? Show me
>> actual good code that doesn't follow this rule. Not just code that
>> technically works because of some statement in the bowels of the
>> standard, but code that has some kind of advantage that is arguably
>> more important than having a simple rule everyone understands and can
>> easily follow.
>
>
> In fact, it is very simple, when the storage to be allocated is larger than the object occupies. inlined_fixed_string in P0722R1 is an example, It uses new (::operator new(full_size)) inlined_fixed_string(data.size(), data.c_str()) to allocate and delete-expression can be used to deallocate.
That's... actually a pretty good example. Though it should be noted
how tied into a specific type it is, and the asymmetry of the
creation/destruction of the object (using a `Make` function, but
`delete` for destruction) is unsightly. I would have used an explicit
`Destroy` function, or better yet, returned a `unique_ptr`, but
whatever.
That being said... how does this apply to IOC? The above code is very
C++, using non-trivial constructors to create the object.
`inlined_fixed_string` is not an implicit lifetime type.
I mean sure, you could take everything out of the constructor and
stick it in `Make` and pretend to make it work. But why would you
*have to*?
Remember: IOC is largely a compatibility feature. It's for code that
needs to work in C and C++, as well as a few edge cases such as
loading from files and the like. But `inline_fixed_string` needs C++;
it has member functions and an `operator delete` overload. It is
categorically not a C API. So why would you rely on IOC when you can
use C++ features directly and much more naturally?
Even if you were #ifdef'ing around the C++ to make it compile as C,
you could just #ifdef around the `new(p) inline_fixed_string` part in
`Make`.
So there's no reason why you would specifically need IOC to play along
with such gymnastics.
Received on 2022-10-02 14:33:41