Thread: Default int construction

  1. #1
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174

    Default int construction

    This is one of the few things I really don't like about C++.

    Code:
    #include <iostream>
    
    struct WrappedInt { int x; };
    
    int main()
    {
        int i;
        int iArray[5];
        WrappedInt wi;
        
        std::cout << i; // 0
        std::cout << *(new int); // 0
        std::cout << int(); // 0
        std::cout << iArray[0]; // undefined
        std::cout << wi.x; // undefined
        
        return 0;
    }
    Does anyone know why?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Why what?

    Why some of them are zero, and might not be?

    For sure, there is no reason why i (case 1) should be zero - that's just dumb luck at the moment.

    For POD types, there is no default constructor, so case 2 would output garbage values in general as well. Again, if you see zero, then that's probably just dumb luck because this is the first time the memory has been allocated.

    int *p = new int; *p = 42; delete p;
    std::cout << *(new int);
    might show a different answer.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Programming King Mr.777's Avatar
    Join Date
    Mar 2011
    Location
    Middle of NoWhere
    Posts
    320
    Also, it depends upon the compiler you are using... Some compilers (older ones) throw garbage if variables are not initialized and some stores 0.
    I don't care if someone doesn't like me, i was not put on earth to entertain everyone.

    No King, no Queen, I am the ACE of battle.

  4. #4
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174
    Hmmm, I guess I'll have to do some more thorough testing. So this is not in the standard? I thought at least one of these cases the int is supposed to be initialized to zero without explicitly saying so.

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Only for static variables or arrays. Otherwise, there is no default initialisation of basic types (int, float, pointers, structs, etc).

    None of the cases you showed involve a default initialisation of the ints to zero.

    Incidentally, accessing the value of any uninitialised variable gives undefined behaviour. Crashing on your code would be just as correct as printing all garbage values, or printing all zeros.

    Testing is also not the way to confirm or deny presence of undefined behaviour - as any behaviour is actually correct.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Programming King Mr.777's Avatar
    Join Date
    Mar 2011
    Location
    Middle of NoWhere
    Posts
    320
    Quote Originally Posted by grumpy View Post
    Only for static variables or arrays. Otherwise, there is no default initialisation of basic types (int, float, pointers, structs, etc).

    None of the cases you showed involve a default initialisation of the ints to zero.

    Incidentally, accessing the value of any uninitialised variable gives undefined behaviour. Crashing on your code would be just as correct as printing all garbage values, or printing all zeros.

    Testing is also not the way to confirm or deny presence of undefined behaviour - as any behaviour is actually correct.
    Agreed but testing can let anyone to be more specific and precise with his/her knowledge... That's what he/she was talking about....
    I don't care if someone doesn't like me, i was not put on earth to entertain everyone.

    No King, no Queen, I am the ACE of battle.

  7. #7
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174
    I've confirmed that the first two cases really are undefined. This pleases me... :-D. I haven't been able to confirm the same for explicitly default constructing the int i.e. "int()", but I suspect this is due to a compiler optimisation.

    I'm having trouble getting the same behaviour out of std::map, which is actually how this started between myself and a friend of mine. Is std::map<int, int> testMap; cout << testMap[rand()]; is supposed to always output zero? Doesn't seem right, or even possible really, but it's weird that I can't get anything other than zero out of it.

    I've been using gcc 4.4.5 for all of this btw.

  8. #8
    Programming King Mr.777's Avatar
    Join Date
    Mar 2011
    Location
    Middle of NoWhere
    Posts
    320
    Try using code blocks or visual studio and you'll see the difference...
    I don't care if someone doesn't like me, i was not put on earth to entertain everyone.

    No King, no Queen, I am the ACE of battle.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    You can't figure out what is/isn't "undefined" simply from observing the behaviour of a limited number of compilers, with a limited sample of code, compiled with a limited set of flags.

    C Draft Standards
    You have to read the standards to find the statements which say "this does ...., otherwise the behaviour is undefined".
    Try here for the C++ drafts - ISO/IEC JTC1/SC22/WG21 - The C++ Standards Committee
    Whilst they are drafts, they are certainly good enough (and importantly, $0 in cost) for anybody who isn't involved in actually writing a compiler.

    It's far too late to find out your "magnum opus" code is broken in lots of ways when you upgrade your compiler, or try to port it to another operating system.

    Write code to the standard, not what your compiler of the moment will let you get away with. You'll use dozens of compilers in a career. Discovering and learning every idiosyncracy is a plain waste of time.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Quote Originally Posted by grumpy View Post
    None of the cases you showed involve a default initialisation of the ints to zero.
    int() is default initialization which for scalar types is the same as zero initialization (2003 standard, 8.5 point 5). If outputting the result doesn't produce a 0 you have bigger problems than undefined behaviour.

    Despite its name, it doesn't happen by default for POD types. Meaning
    Code:
    int i; // i = ???
    // and 
    int j = int(); // j = 0
    are two completely different things
    Last edited by adeyblue; 03-22-2011 at 10:07 AM.

  11. #11
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Quote Originally Posted by Mozza314 View Post
    This is one of the few things I really don't like about C++.
    ...
    Does anyone know why?
    I have no idea why you don't like it, but I've got a tip: always initialize, no matter if static or not.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by adeyblue
    int() is default initialization which for scalar types is the same as zero initialization (2003 standard, 8.5 point 5).
    More accurately, it is value-initialization.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Mozza314 View Post
    Does anyone know why?
    One of the explicit goals of C++ is that you do not need to pay for something you do not use. Initializing every local POD variable to zero is, in most cases, just a waste of time, as the variable will shortly thereafter be assigned some other value anyway.

    Initializing globals and statics, on the other hand, costs nothing, because due to the way things happen when an executable loads, these things must be given specific values anyway -- in fact, it would cost more to make them undefined than it does to define them to something (what would you do, call a random number generator to make sure some unpredictable value gets placed there?). In that case there is no price to pay for the initialization and so they are initialized.

    Even with a class that has an explicit constructor, you can choose to not initialize member variables if that's what you want.

    EDIT: By "explicit constructor" I mean a constructor that you deliberately wrote, not a constructor that's declared with the "explicit" keyword.
    Last edited by brewbuck; 03-22-2011 at 11:58 AM.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  14. #14
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174
    Quote Originally Posted by adeyblue View Post
    int() is default initialization which for scalar types is the same as zero initialization (2003 standard, 8.5 point 5). If outputting the result doesn't produce a 0 you have bigger problems than undefined behaviour.
    This is what is bizarre to me. So there is an exception for scalar types - the default construction (and floats, doubles, etc. I take it) depends on the context of the default construction.


    Quote Originally Posted by brewbuck View Post
    One of the explicit goals of C++ is that you do not need to pay for something you do not use. Initializing every local POD variable to zero is, in most cases, just a waste of time, as the variable will shortly thereafter be assigned some other value anyway.
    I understand that, in fact, it's what I want! :-P. It's not the unpredictable initial values that bother me, but the ones that are (at least at the time seemed to be) predictable. I've always had the habit of always initialising scalar types before using them, and I consider it bad practice not to - so I want my code to break if I somehow forget to do it.

    Why are those unpredictable values so frequently zero anyway? Does memory usage by its nature just use a lot of zeros? Surely not? Does that mean something is going through and clearing that memory every so often? Actually I think I know... does the operating system do it for security reasons before giving the process more memory so that it can't access memory used by other programs?


    Quote Originally Posted by brewbuck View Post
    Initializing globals and statics, on the other hand, costs nothing, because due to the way things happen when an executable loads, these things must be given specific values anyway -- in fact, it would cost more to make them undefined than it does to define them to something (what would you do, call a random number generator to make sure some unpredictable value gets placed there?). In that case there is no price to pay for the initialization and so they are initialized.
    This exception I understand. There's a good reason there. Although I probably would prefer if each compiler could just pick some strange value each build (or each compiler version maybe) and use that instead of zero. I guess the standards committee isn't particularly interested in defensive features like this... like how a member function is implicitly virtual if it overrides a virtual function in the base class. If it were up to me I would have required the virtual keyword to override a virtual function, and made failing to do so an error.

  15. #15
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    4 To zero-initialize an object of type T means:
    — if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted
    to T;94)
    — if T is a non-union class type, each non-static data member and each base-class subobject is zero-initialized;
    — if T is a union type, the object’s first named data member95) is zero-initialized;
    — if T is an array type, each element is zero-initialized;
    — if T is a reference type, no initialization is performed.
    5 To default-initialize an object of type T means:
    — if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed
    if T has no accessible default constructor);
    — if T is an array type, each element is default-initialized;
    — otherwise, the object is zero-initialized
    By my reading of the standard the promise is that a POD scalar type is zero initialized, but what zero initialized means is explained here. int x(); does not zero initialize. You have to supply an expression.
    Last edited by whiteflags; 03-22-2011 at 04:58 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. stdio.h?
    By kiros88 in forum C Programming
    Replies: 5
    Last Post: 05-21-2010, 07:09 PM
  2. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  3. can some one please tell me the cause of the error ?
    By broli86 in forum C Programming
    Replies: 8
    Last Post: 06-26-2008, 08:36 PM
  4. Replies: 3
    Last Post: 05-13-2007, 08:55 AM
  5. easy if you know how to use functions...
    By Unregistered in forum C Programming
    Replies: 7
    Last Post: 01-31-2002, 07:34 AM