C++ Logo


Advanced search

Re: [std-proposals] A type trait to detect if value initialization can be achieved by zero-filling

From: Giuseppe D'Angelo <giuseppe.dangelo_at_[hidden]>
Date: Mon, 30 Jan 2023 02:36:27 +0100

Il 29/01/23 22:11, Jason McKesson via Std-Proposals ha scritto:
> On Sun, Jan 29, 2023 at 3:41 PM Giuseppe D'Angelo via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>> Hello,
>> As per subject, I've been working on a proposal for a standardized way
>> to detect if a trivially default constructible type can be value
>> initialized by using `memset(0)` on some suitable storage.
>> A draft is available here:
>> https://isocpp.org/files/papers/D2782R0.html
>> As usual, any early feedback is very much appreciated. I am not 100%
>> convinced about the name of the trait, as I'm trying to model something
>> for which there isn't already an established name/concept. I hope the
>> discussion/bikeshedding can wait after everything else has been ironed
>> out...
> I don't like that the set of such types is so broadly
> implementation-defined. We need something more concrete.

Thank you for the feedback!

So, rather than just hand-waving the semantics, would you prefer a
stronger classification of such types (say, in [basic.types.general] and
[class.prop]) and then the trait simply refers to the classification? I
guess I can work with that.

> I would suggest that a type is "trivially zero-initializable" if:

Without going immediately into naming bikeshedding, I was deliberately
steering away from _anything_ with "zero-init" in its name, as "zero
initialization" has well-established semantics which are not what I'm
looking for. To zero-initialize a pointer does not necessarily mean fill
its storage with zeroes :-(

"(trivially) value-initializable by zero-filling" is a complete mouthful
but would be spot-on.

> 1. If it is a class type:
> 1a. It is an implicit lifetime type
> 1b. All of its non-static data members and base classes are
> themselves implicit lifetime types

I'll answer the other message regarding implicit lifetime types...

> 2. It is an arithmetic type
> 3. It is an enumeration type
> 4. It is `nullptr_t`

Devil's advocate: are there any guarantees that this is the case? Is an
implementation allowed to use (uint)-1 as object representation of
objects of type `nullptr_t` and to actually implement
operator==(nullptr_t a, nullptr_t b) as `return a==b;`?

I'd just fold it into the "implementation defined".

> 5. The other fundamental types are all implementation defined.

> However, I would suggest that it should be equally true/false for all
> pointers of the same category: object pointers, function pointers, and
> member pointers. Either all object pointers are
> trivially-zero-initializable or none of them are. Etc.

Is there any reason for this? On Itanium, pointers to objects and to
functions can be zero-filled. Pointers to data members cannot. Why not
having the trait giving the factually correct answer? Surely one would
want a vector of `string_view`s to be zero-filled.

> 6. No reference types are trivially-zero-initializable.
> Also, how does Itanium-based code work if you have a member pointer in
> static storage that gets zero-initialized? Does something have to
> manually fill in the -1s at runtime, or does an object containing such
> a member pointer have to take up space in static executable storage?

Could you please elaborate on this question? "Normally" it ends up
eating space in .data, and not folded in .bss. Whether it's filled at
compile time or runtime depends on if you're initializing it with a
constant expression or not...?

Thank you,
Giuseppe D'Angelo

Received on 2023-01-30 01:36:30