0

(not rubbish only if zero initialized as static scope member.) and it works as expected on GCC!(((

So for code like:

#include <iostream>
#include <boost/shared_ptr.hpp>

namespace SP
{
    // enums
    enum EnumMessage {
        EnumMessage_EventBase = 0,
        EnumMessage_EventServiceBase = 1,
        EnumMessage_OperationBase = 2
    };

    class Message;

    // define proxy class
    class Message  {
    public:
        EnumMessage _MessageCode;
    };

    class Parent : public Message {
    public:
        int _ServiceId;
        int _CallbackId;
    };

    class Child : public Parent {
    public:
        std::string _Debug;
    };

    class AnotherChild : public Parent {
    public:
        int _UserId;
    };
}

using namespace SP;

int main() {
    //OK
    static Child staticScopeChild = Child();
    boost::shared_ptr<Parent> ptrParent(new Parent());
    boost::shared_ptr<AnotherChild> ptrChild2(new AnotherChild());

    //Bad
    Child scopeChild = Child();
    boost::shared_ptr<Child> ptrChild(new Child());


    std::cout << "static " << staticScopeChild._MessageCode 
        << std::endl << "vs scope " << scopeChild._MessageCode 
        << std::endl << "vs pointer " << ptrChild->_MessageCode 
        << std::endl << "vs parent class pointer: " << ptrParent->_MessageCode 
        << std::endl << "vs another parent child: " << ptrChild2->_MessageCode <<std::endl;
    std::cin.get();
    return 0;
}

where all classes are generally PODs (ints, enums) I get next output:

static 0
vs scope -858993460
vs pointer -842150451
vs parent class pointer: 0
vs another parent child: 0

while I expected all to be 0!

Why can such thing happen?

myWallJSON
  • 9,110
  • 22
  • 78
  • 149
  • And I have such bad zero initialization for all classes in that branch up that child... While all goes Ok in all other branches which seem not diferent from that broken one.((( – myWallJSON Jan 24 '13 at 12:06
  • Show us `Child` constructor. – Tadeusz Kopec for Ukraine Jan 24 '13 at 12:10
  • 2
    It sounds like the constructor of `Child` doesn't initialise `$MessageCode`; so static objects will be zero-initialised and others will have indeterminate values. But without seeing the constructor, I can only guess. – Mike Seymour Jan 24 '13 at 12:10
  • 1
    (By the way, it's not portable to use `$`, or any non-alphanumeric character except `_`, in an identifier.) – Mike Seymour Jan 24 '13 at 12:12
  • @MikeSeymour there is no Child or Parent or AnotherChild constructor - we rely on ones VS generates for us. also seems like It is possible to use `$` - our code compiles and even works to some extent...) – myWallJSON Jan 24 '13 at 12:13
  • @myWallJSON: Indeed, some compilers accept "other implementation-defined characters", and if you don't need portability then that's fine. I was just pointing out that it wasn't portable, in case that's an issue for you. – Mike Seymour Jan 24 '13 at 12:15
  • @myWallJSON: Perhaps you could post the definition of `Child`, perhaps removing as much as you can while still exhibiting the problem. *If* the classes are POD, then `Child()` should value-initialise all the members to zero; but without seeing the code, we can only guess why that's not happening. – Mike Seymour Jan 24 '13 at 12:18
  • @MikeSeymour: Sample code added. – myWallJSON Jan 24 '13 at 12:34
  • I wouldn't expect enums to be 0. Maybe it's valid C++, and maybe I knew this long ago, but from all the weirdness of VC++ you should start forgetting "tricks" and just go and stuff the compiler's mouth with code of YOUR choice... *angry rant* – ActiveTrayPrntrTagDataStrDrvr Jan 24 '13 at 12:39
  • Remember that enums are compile-time values, and they start at 0 by default. – Qix - MONICA WAS MISTREATED Jan 24 '13 at 12:47
  • @ActiveTrayPrntrTagDataStrDrvr: enums, like any other scalar type, should be initialised to zero (converted to the enumeration type) by value-initialisation. – Mike Seymour Jan 24 '13 at 13:06
  • 1
    Look at the answers... it's the "VC++ weirdness" I'm talking about. If you let VC2010 to handle anything that you forgot to specify, get ready to stumble hard. I don't know about VC2012. I've been in this boat for 8 years. – ActiveTrayPrntrTagDataStrDrvr Jan 24 '13 at 13:38

1 Answers1

4

It appears to be a compiler bug: according to this report members of base classes are not zero-initialised during value-initialisation of the derived class.

As far as I can see, there is nothing wrong with your code, and all class members should be zero-initialised on a conforming C++03 or C++11 compiler.

I guess your options are:

  • make the classes more POD-like by avoiding inheritance; or
  • add default constructors to any base classes to explicitly zero-initialise all members; or
  • use a less broken compiler.
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Avoiding inheritance won't make the classes POD, as `Child` contains a member of type `std::string` that is not POD. I like the last suggestion though :) -- +1 as the answer is correct in that the members should be zero-initialized before the default constructor is called. – David Rodríguez - dribeas Jan 24 '13 at 14:50
  • @DavidRodríguez-dribeas: That's true. But without inheritance it might be POD-like enough for value-initialisation to work, though. – Mike Seymour Jan 24 '13 at 14:52
  • Please submit a bug report and lets see official answer. – myWallJSON Feb 04 '13 at 20:48
  • @myWallJSON: Someone already has - see the [link](https://connect.microsoft.com/VisualStudio/feedback/details/746973/incorrect-c-11-value-initialization-for-type-with-implicitly-declared-but-non-trivial-default-constructor) I included in the first sentence of the answer. – Mike Seymour Feb 05 '13 at 11:39