VC++ does not value-initialize members of derived classes without user-declared constructor - by Sylvester Hesp

Status : 

  Won't Fix<br /><br />
		Due to several factors the product team decided to focus its efforts on other items.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.


15
0
Sign in
to vote
ID 484295 Comments
Status Closed Workarounds
Type Bug Repros 6
Opened 8/20/2009 3:11:35 PM
Access Restriction Public

Description

When value-initializing an object that hasn't have a user-declared ctor, the standard clearly says that each member and baseclass of that object should be value-initialized.

From ISO/IEC 14882:2003:
-----------------------------------------------------------------
8.5/8
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

-And-

8.5/5
To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized
-----------------------------------------------------------------

In the example program below (see "Steps to reproduce"), both Foo1 and Foo2 are classes without user-declared constructors. Yet, only the members of Foo2 are actually value-initialized when value-initializing the Foo2 object. The members of Foo1 remain default-initialized (which means uninitialized for basic types like 'int'). But the only difference is that Foo1 has a base class, while Foo2 doesn't. To me there seems to be no reason why the members of Foo1 shouldn't be value-initialized when Foo1 itself is being value-initialized, and the compiler is clearly in violation of the standard on this point.

Not only that, it can seriously break programs when someone decides to give a certain class or struct a base class, thereby removing all value-initialization of their members that the programmer might have been counting on. Additionally, such a bug would be very difficult to track down. And I can't imagine anyone counting on the current behaviour that a value remains uninitialized, especially when it only remains uninitialized when the class has a base class.

This also happens in older VC++ compilers and the Xbox 360 compiler.
Sign in to post a comment.
Posted by Chardrazle on 11/20/2014 at 2:44 AM
Another 'for the record'. We just got tripped up by this issue. We're targeting multiple platforms, and code that was working correctly on the other platforms (with the 'other' compiler) just fell over on Windows due to this.

Using MSVC (cl) version: 18.00.31010 for x64.

Come on guys, "won't fix"? This is a standards-compliance issue.

Note: I find the demo code sometimes compiles to produce the (desired) zero-value outputs. I find it helps to 'churn up' the memory a little beforehand, e.g.:

<snip>
int wmain()
{
    for (size_t n = 0; n < 100; ++n)
    {
        char *p = new char[100];
        for (char m = 0; m < 100; ++m)
        {
            p[m] = m;
        }
        delete[] p;
    }

    std::cout << Foo1().i << std::endl;
    std::cout << Foo2().i << std::endl;
}


Our compiler line:
cl -c -nologo -Zm200 -Zc:wchar_t -FS -Zi -MDd -EHsc -GR -W3 -w34100 -w34189 msvc_value_init.cpp
Posted by Niels Dekker on 8/25/2014 at 8:11 AM
Good news: it appears that this compiler bug is finally fixed! As Kangyuan Niu (Microsoft) wrote in a comment at http://blogs.msdn.com/b/visualstudio/archive/2014/07/08/visual-studio-14-ctp-2-available.aspx on August 21, 2014: 'Neither 499606 nor 484295 can be reproduced in Visual Studio "14" CTP 3'

I just tried to reproduce both Bug ID 499606 and 484295, after having installed VS "14" CTP 3 (compiler version 19.00.22013.1), but indeed, I failed, twice :-)

@Microsoft: If this bug is indeed fixed, as it seems, please mark it as "Fixed", instead of "Won't Fix".
Posted by Niels Dekker on 8/10/2014 at 9:25 AM
For the record, I just reproduced this bug with Visual Studio 2013 Update 3 as well (CL.EXE compiler version 18.00.30723 for x86).
Posted by TheArtTrooper on 10/13/2011 at 12:09 AM
I reproduced this problem with Visual C++ 11 (part of Visual Studio 11 Developer Preivew). CL.EXE reports version 17.00.40825.2 for 80x86.
Posted by Niels Dekker on 4/25/2010 at 2:57 AM
Note: it looks like this report by Sylvester Hesp is related to a report by Pavel Kuznetsov: "Value-initialization in new-expression", https://connect.microsoft.com/VisualStudio/feedback/details/100744
Posted by Microsoft on 8/25/2009 at 9:55 AM
Hi: I can confirm that this is a bug with Visual C++. Unfortunately it does not meet the triage bar for the current release of Visual C++ - but we will keep the issue in our database and we will look at it again during the development phase of a future release of Visual C++.

Jonathan Caves
Visual C++ Compiler Team
Posted by Microsoft on 8/23/2009 at 9:58 PM
Thanks for your feedback. We are routing this bug to the product unit who works on that specific feature area. The team will review this issue and make a decision on whether they will fix it or not for the next release.

Thank you,
Visual Studio Product Team