[cfe-dev] [RFC] automatic variable initialization

Arthur O'Dwyer via cfe-dev cfe-dev at lists.llvm.org
Wed Jan 16 20:30:49 PST 2019


Kostya,
It sounds like the current approach is utterly conservative: if it sees a
call to a constructor in a different translation unit (TU), then it won't
assume anything about that constructor's behavior.  (For all we know, that
constructor's TU might have been compiled without the zero-init flag.)
This can lead to O(N) redundant initializations:

    struct A { A(); int i; };
    struct B : A { B(); };
    struct C : B { C(); };
    // The TU that defines A::A() will initialize `i`.
    // The TU that defines B::B() can't see that `i` will be initialized by
A::A(), so it redundantly initializes `i`.
    // The TU that defines C::C() can't see that `i` will be initialized by
A::A() or B::B(), so it redundantly initializes `i`.

However, this is all because of the current conservative approach, where
our TU-compiled-with-zero-init must assume that other TUs were perhaps *not*
compiled with zero-init.
Richard is saying that you could instead make zero-init an all-or-nothing
proposition. Then, B::B() would say "I don't see the definition of A::A()
yet, but, since I am being compiled with zero-init, I will assume that that
other TU is also going to be compiled with zero-init. So `i` *will* be
initialized; so therefore I don't have to initialize it myself."  And so
all the redundant initializations would disappear.

If it later turned out that the TU containing A::A() had not been compiled
with zero-init... well, then `i` might remain uninitialized. But so might
any variable that began its life in that other TU. So I don't think there's
any philosophical problem there.

I think the "all-or-nothing" approach is probably the right approach.  Let
each constructor worry about initializing its data members. Don't
second-guess the constructor just because you can't see its definition.

HTH,
–Arthur

On Wed, Jan 16, 2019 at 10:58 PM Richard Smith via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> On Wed, 16 Jan 2019, 19:35 Kostya Serebryany via cfe-dev <
> cfe-dev at lists.llvm.org wrote:
>
>>
>>>
>>> Should main be involved, though?
>>>
>>
>> How else?
>>
>
> By putting the initialisation where it belongs, in the constructor.
>
> main() creates a local variable on stack and passes it's address to a
>> CTOR, that (in general case) is unknown at the point where we insert
>> initialization.
>>
>>
>>
>>> It's normally the job of the constructor to initialize the class
>>> members, and that's where the information about whether the members are
>>> uninitialised lives.
>>>
>>>>
>>>>>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190116/0f2eef2c/attachment.html>


More information about the cfe-dev mailing list