18

An hour ago I posted an answer here which according to me was correct. However my answer was downvoted by Martin B. He said

You're just lucky and are getting zeros because the memory that i was placed in happened to be zero-initialized. This is not guaranteed by the standard.

However after reading Michael Burr's answer here and trying the following sample code

1)

#include <cassert>

struct B { ~B(); int m; };

int main()
{
   B * b = new B();
   assert(b->m == 0);
}

I got a debug error on MSVC++ 2010.

I got a similar error when I tried the following code [My answer here] on MSVC++2010

2)

#include <cassert>
struct Struct {
    std::string String;
    int Int;
    bool k;
    // add add add
};

struct InStruct : Struct
{
   InStruct() : Struct() {}
};

int main()
{
   InStruct i;
   assert(i.k == 0);
}

Neither (1) nor (2) gave any such error on gcc/Clang which made me think if MSVC++2010 does not support C++03. I am not sure.

According to Michael Burr's post [in C++03]

new B() - value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined.

The Standard says

To value-initialize an object of type Tmeans:

— 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 Thas no accessible default constructor);

.....

otherwise, the object is zero-initialized

From the first point if there is no user declared default constructor the compiler synthesized default constructor will be called which will zero initialize all the fields (according to last point).

So where am I wrong? Is my interpretation of value initialization correct?

Community
  • 1
  • 1
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • 6
    It's your compiler: http://connect.microsoft.com/VisualStudio/feedback/details/564268/c-value-initialization http://connect.microsoft.com/VisualStudio/feedback/details/484295/vc-does-not-value-initialize-members-of-derived-classes-without-user-declared-constructor https://connect.microsoft.com/VisualStudio/feedback/details/100744/value-initialization-in-new-expression – CB Bailey Oct 14 '10 at 08:23
  • 4
    @Charles : Thanks a lot for these links. If you post that[your comment] as an answer I will accept it. `:)` – Prasoon Saurav Oct 14 '10 at 08:34
  • @Charles Bailey: Really, that actually answers the question. Why is that not an answer? – sharptooth Oct 14 '10 at 08:45
  • So it means that the zero initialization is guaranteed by the standard but is a bug in VC compilers. So Martin B's comment is not correct? – Naveen Oct 14 '10 at 08:49
  • @Naveen : Yes! His comment is incorrect :) – Prasoon Saurav Oct 14 '10 at 08:53
  • 2
    @Naveen: Yes. Likely, he had experienced this in VS and concluded incorrectly. It's a shame something so basic isn't implemented correctly. – GManNickG Oct 14 '10 at 08:53
  • @sharptooth: I thought this would get 'closed as duplicate' pretty quickly but thought a quick comment would help. I couldn't really be bothered to answer but I've conceded. – CB Bailey Oct 14 '10 at 09:00
  • 1
    To all: Thanks for educating me! – Martin B Oct 14 '10 at 09:07
  • @Charles : Dupe to which question? I don't think this has been asked before at SO. I may be wrong. :) – Prasoon Saurav Oct 14 '10 at 09:14
  • I'm sure I've _answered_ this problem here before but I can't now find where. – CB Bailey Oct 14 '10 at 09:48
  • The second example with "T v;" has no initialization at all. Just seeing zeros does not mean they are mandated by the standard. – eel ghEEz Jun 19 '16 at 13:24

2 Answers2

33

Visual Studio has known bugs in all current versions (2005, 2008, 2010) where it doesn't correctly implement value-initialization for non-POD types that don't have a user declared constructor.

By the language rules none of you asserts should fire but do exhibit the compiler issues. These are some of the bug reports, note that they are all closed or resolved as "Won't Fix".

http://connect.microsoft.com/VisualStudio/feedback/details/564268/c-value-initialization

http://connect.microsoft.com/VisualStudio/feedback/details/484295/vc-does-not-value-initialize-members-of-derived-classes-without-user-declared-constructor

http://connect.microsoft.com/VisualStudio/feedback/details/100744/value-initialization-in-new-expression

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 1
    +1 and... wow, I carefully read into those feeback items and I'm shocked. In the first snippet by OP the problem will only occur if there's a user-provided destructor. If there's no user-provided destructor the variable is properly initialized. So this makes room for numerous code defects and all sane Visual C++ developers should better be aware of this problem. – sharptooth Oct 14 '10 at 09:55
  • This is a new learning for me. I also thought language doesn't provide any initialization guarantee. Just can't understand what prevents Microsoft from fixing such an important and basic bug. – Naveen Oct 14 '10 at 10:19
  • 2
    @Naveenn: Existing code base. I think they should at least issue a warning every time they don't implement things correctly (like their laxism with `typename` keyword) – Alexandre C. Nov 09 '10 at 19:53
  • 7
    @sharptooth: "all sane Visual C++ developers", I don't know how you can remain sane while using Visual C++. The only way I found to retain my sanity was to stop using it :x – Matthieu M. Nov 17 '11 at 07:18
  • 1
    @Matthieu M. So you switched to..? – mlvljr Feb 25 '12 at 20:05
  • 1
    @mlvljr: CodeBlocks backed by clang over mingw. Next step is having a full Linux running in a VM for compilation. Of course it helps that I only played with Visual Studio "for fun" and don't have to deliver Windows soft ;) – Matthieu M. Feb 26 '12 at 11:58
  • @Matthew M. Reading your answer at http://stackoverflow.com/a/6530973/110118 suggests this is somewhat not trivial, or am I mistaken here? (may be the things did improve since summer, etc) – mlvljr Feb 26 '12 at 12:27
  • Won't Fix implies that Microsoft's software could break if run on a standards conforming compiler. Do they offer a non-default-but-conforming compiler option? – BSalita Oct 23 '12 at 00:51
  • The last link had a comment from a Visual Studio developer who disagreed, http://web.archive.org/web/20101022045356/http://connect.microsoft.com/VisualStudio/feedback/details/100744/value-initialization-in-new-expression but a reply suggested that he mis-interpreted the standard's definition of "new T" as "new T()". I see cppreference.com saying that c++03 and subsequent versions parse "new T()" as value initialization whereas older versions considered that a non-zeroing default initialization. – eel ghEEz Jun 19 '16 at 14:25
9

For people who stumble upon this question in 2015, like me:

All of the above issues have been fixed in VS 2015. Value initialization now works as defined in the standard.

Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
CodeMonkey
  • 704
  • 1
  • 6
  • 15