C++ Logo


Advanced search

Subject: Re: [std-proposals] Allowing access to object representations
From: Brian Bi (bbi5291_at_[hidden])
Date: 2019-08-19 16:40:18

On Mon, Aug 19, 2019 at 4:37 PM Brian Bi <bbi5291_at_[hidden]> wrote:

> On Mon, Aug 19, 2019 at 4:20 PM language.lawyer--- via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>> >> The creation of an object of type T would end the lifetime of the array
>> >> elements, so accessing them would be UB.
>> >>
>> >
>> > An array of unsigned char or std::byte can have an object of some other
>> > type nested within it, so the array's lifetime is not ended.
>> Right, but I wrote that the lifetimes of the array *elements* would end.
>> There is no "nested within" relation between the elements and an object
>> which is placed over them.
> [intro.object]/3
> If a complete object is created ([expr.new]
> <http://eel.is/c++draft/expr.new>) in storage associated with another
> object e of type “array of N unsigned char” or of type “array of N std::
> byte” ([cstddef.syn] <http://eel.is/c++draft/cstddef.syn>), that array *provides
> storage* <http://eel.is/c++draft/basic.memobj#def:provides_storage> for
> the created object if: ...
> [intro.object]/4
> An object a is *nested within*
> <http://eel.is/c++draft/basic.memobj#def:nested_within> another object b if:
> *...* or b provides storage for a, or ...
> [basic.life]/1
> The lifetime of an object o of type T ends when: ... the storage which
> the object occupies is released, or is reused by an object that is not
> nested within o ([intro.object]
> <http://eel.is/c++draft/basic.memobj#intro.object>).
> <http://eel.is/c++draft/basic.memobj#basic.life-1.sentence-4>
>> >> This just shows that the access to object representations do not fit
>> well
>> >> into the current model of the C++ abstract machine.
>> >>
>> >
>> > Indeed. On one hand, one could conclude that people who want to access
>> > object representations should just suck it up. On the other hand, one
>> could
>> > observe that the current C++ memory and object model results in a lot of
>> > pre-C++17 code being broken, and conclude that it should be revised.
>> >
>> > Besides, even if you think that no one should ever try to access object
>> > representations of anything much more complicated than a struct with a
>> > bunch of ints in it, do you think it is reasonable to limit typical
>> usage
>> > of offsetof to such types as well? If I have a pointer to a member of
>> some
>> > class that is standard-layout but not implicit-lifetime, should there
>> not
>> > be a way for me to get a pointer to the enclosing class using pointer
>> > arithmetic? Are you comfortable with letting all the existing code of
>> this
>> > form, written before C++17, continue to be broken? What did we gain from
>> > the C++17 changes that was so beneficial that it justified *silently
>> > breaking* said code? What about the fact that the migration effort for
>> such
>> > code can be significant (given, as I've pointed out, the inadequacies of
>> > the proposed std::bless solution)?
>> Isn't offsetof usually used in some low-level code which typically also
>> breaks the strict aliasing rule?
>> There are compiler flags making the later behavior defined.
>> It is not forbidden for implementations to define behavior which the
>> standard does not define.
> I don't see why that is necessarily the case. It could, for example, be
> used to allow a user to remove an object from a node-based container given
> a pointer to the object. There's no reason why such code should have to
> depend on special flags to make strict aliasing violations well-defined.
> Oh, sure, you can rewrite the container so that its API is based on
> iterators instead, to avoid this problem---and, of course, you'll also have
> to rewrite ALL the code that uses it. As I said, the migration effort is
> "significant".

Sorry, to be clear, I meant there is no reason why such code would be
written in a way that violates strict aliasing, so one would not have the
need to enable such flags to build it, and I also don't think such code is
necessarily so "low-level" that it's reasonable to force everyone who needs
to build it to enable some obscure compiler flag that they're not already

>> >>>> I do not think that this is a good way.
>> >>>>
>> >>>
>> >>> What problem did this cause when it was effectively the status quo in
>> >>> C++14, that is so serious that we should not attempt to codify it in
>> >> C++23
>> >>> or some future version of the standard?
>> >>
>> >> I do not think calling bytes of memory "objects" is a good status quo.
>> >>
>> >
>> > Is that really your only objection? Presumably, it would be possible to
>> > word the changes to the standard in a way that would avoid this. The
>> point
>> > is that existing code relies on being able to do pointer arithmetic on
>> > memory that various types of objects occupy *as though* an array of
>> unsigned
>> > char objects existed there. We don't have to say that there are actual
>> > objects. Given the way pointers work in C++17, I think this would
>> require a
>> > lot of wording, but I think I've already stated enough times how the
>> > alternative of doing nothing leaves a lot of code broken.
>> I don't know the solution for this problem :/
> I don't know the solution either, but I felt it was important to point out
> how "just use std::bless" is not a solution.
> It's good that we're at least talking about the OP's proposal (although I
> can't access it right now... what happened to the github link?)
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> --
> *Brian Bi*

*Brian Bi*

STD-PROPOSALS list run by std-proposals-owner@lists.isocpp.org

Standard Proposals Archives on Google Groups