C++ Logo

std-proposals

Advanced search

Re: [std-proposals] all bytes zero == null object

From: Breno Guimarães <brenorg_at_[hidden]>
Date: Mon, 22 Jul 2024 11:22:55 -0300
You could have the trait and functions the user could specialize to invalid
bit patterns about the type:

template<class T> struct std::has_invalid_bit_pattern : public
std::false_type {};
template<class T> void std::set_invalid_bit_pattern(std::byte* data) {}
template<class T> bool std::is_invalid_bit_pattern(const std::byte* data) {
return false; }

Then std::optional could use those traits to check and set those bit
patterns. It could be useful for many other containers too.

Breno G.


On Mon, Jul 22, 2024 at 10:59 AM Thiago Macieira via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On Sunday 21 July 2024 09:51:17 GMT-7 Frederick Virchanza Gotham via Std-
> Proposals wrote:
> > Typically when implementing a class such as 'std::optional', the size
> > of 'std::optional<T>' is equal to "sizeof(T) + 1u", because one more
> > byte is needed to store a boolean to indicate whether there is a valid
> > object in existence.
>
> That means it's 2*sizeof(T) in total size.
>
> > We can use "__datasizeof" or "[[no_unique_address]]" in order to try
> > use the tail padding of T to store the boolean, and if we succeed,
> > then sizeof(optional<T>) == sizeof(T).
>
> QoI. We don't need a core language change for this.
>
> > If T has no tail padding, then we need an extra byte to store the
> > boolean. Unless . . . we had the ability to mark the class
> > 'null_bytes==null_object" as follows:
> >
> > class T (null_bytes==null_object) {
> > . . .
> > };
>
> No, we cannot do that. Let's take the example of a null pointer, which in
> most
> architectures is a bitwise zero. A std::optional<T *> containing a null
> pointer is not semantically the same thing as a disengaged std::optional.
> For
> some tasks it may be important to return "any pointer including null" and
> differentiate from "sorry, I failed".
>
> Let me take another example: QString. Its null-bytes representation is
> simply
> d = nullptr, ptr = nullptr and size = 0, which is the representation of a
> default QString(). So same as the pointer case above, this is not the same
> as
> a disengaged std::optional<QString>.
>
> On the other hand, a std::optional<std::errc> could use the value zero as
> "disengaged" because that is not a value used by the enumeration. Though
> most
> likely, that would be used by std::expected instead of optional, where
> semantically it means something.
>
> I like the idea of a compact representation, but it needs to be informed
> by a
> traits class. Ideally it would allow the trait to inspect the bytes to
> determine validity, but that is going to run into a discussion on how to
> do it
> without UB on the storage without having constructed the object there. It
> might not be necessary to inspect all bytes of the object, for one thing.
>
> Needless to say, this needs to be opt-in, not opt-out.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Principal Engineer - Intel DCAI Platform & System Engineering
>
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2024-07-22 14:23:07