Why does adding a struct constructor result in uninitialized struct fields?

25 views
Skip to first unread message

Simon Que

unread,
Apr 12, 2016, 12:17:14 AM4/12/16
to Chromium-dev, Lei Zhang, Will Harris
One of my CLs caused the Asan and Msan bots to fail:

The problem is when LeakDetectorImpl::RecordAlloc() attempts to access the struct member var |AllocSizeEntry::stack_table| (pointer type), which is uninitialized.

My CL didn't change this code but it did add an empty constructor/destructor for struct AllocSizeEntry (defined in leak_detector_impl.h) -- it was a requirement for adding a non-POD member that was an STL container |call_site_breakdown_history|. Apparently a side effect of adding the constructor was that |stack_table| is uninitialized.

This leaves me wondering how this code actually passed Asan and Msan before this CL. Is uninitialized data a known side effect of adding an empty constructor to a struct? I would think that the field was already uninitialized before.

Simon

Scott Hess

unread,
Apr 12, 2016, 12:20:16 AM4/12/16
to Simon Que, Chromium-dev, Lei Zhang, Will Harris
POD structures are default zero-initialized.  When you added the explicit constructor, it assumed you were initializing all the things you wanted to initialize.

-scott


--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev

Simon Que

unread,
Apr 12, 2016, 12:33:19 AM4/12/16
to Scott Hess, Chromium-dev, Lei Zhang, Will Harris
I'm assuming you mean POD structures have a default ctor that zero-initializes them, but still has to be invoked somehow.

In the case of my code, this struct was sitting in a vector that was initialized to a non-zero size, invoking this default ctor. If I had created the struct as a local variable without parentheses, would it still have been zero-initialized?

i.e. given a struct Foo { int x, y; }, I'm guessing that:

  Foo f;   // No ctor invocation -> contains garbage
  Foo f();  // Explicit ctor invocation -> zero-initialized

Trent Apted

unread,
Apr 12, 2016, 1:03:32 AM4/12/16
to sq...@chromium.org, Scott Hess, Chromium-dev, Lei Zhang, Will Harris
nit: STL collections will explicitly "default initialize" (C++98 terminology) or "value initialize" (C++03 terminology) the objects they contain when resizing/initializing.

E.g. for a 

std::vector<Foo> foo(2);

It's like doing

foo[0] = Foo();
foo[1] = Foo();

likewise

std::vector<int> bar(2);

does

bar[0] = int();
bar[1] = int();


For primitives "value initialize" is the same as "zero initialize". For class types there a bunch of rules - see "The effects of value initialization" at http://en.cppreference.com/w/cpp/language/value_initialization . But for this case, "if T is a class type with a default constructor that is neither user-provided nor deleted the object is zero-initialized". But if it has a constructor, that's called, and uninitialized members stay uninitialized.





Reply all
Reply to author
Forward
0 new messages