Like Tree2Likes

Default int construction

This is a discussion on Default int construction within the C++ Programming forums, part of the General Programming Boards category; Originally Posted by Mozza314 Why are those unpredictable values so frequently zero anyway? Does memory usage by its nature just ...

  1. #16
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Quote Originally Posted by Mozza314 View Post
    Why are those unpredictable values so frequently zero anyway? Does memory usage by its nature just use a lot of zeros? Surely not?
    Actually, yes. The distribution of values in most programs follows a roughly Zipfian distribution, which is a simple power law. The smaller a value is the more frequently it occurs. Obviously this is not a law of nature, just an observation.

    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?
    Yes, in fact, on a Windows system when a core has nothing to do it runs the "ZeroPage" process whose sole purpose is to riffle through memory clearing out pages which aren't in use. Whenever you get a page from the OS it is zero-cleared -- it saves time if that clearing happens in the background instead of at the moment you allocate the page.

    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.
    You have to remember that C and C++ were designed back when things like this actually mattered a lot. It takes time and memory to initialize values -- time, because you need to stick the value in there. Memory, because you need to have instructions which do that, and instructions take up space. As I mentioned before, zero is often what you wanted anyway, so zero is the default.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  2. #17
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174
    So, to summarise, if I understand what's been said correctly,

    Code:
    #include <iostream>
    
    int globalInt;
    
    struct WrappedInt
    {
        int mX;
    };
    
    int main()
    {
        int autoInt;
        int intArray[5];
        WrappedInt wi;
        static int staticInt;
    
        std::cout << autoInt << std::endl;        // undefined
        std::cout << *(new int) << std::endl;     // undefined
        std::cout << int() << std::endl;          // 0
        std::cout << intArray[0] << std::endl;    // undefined
        std::cout << wi.mX << std::endl;          // undefined
        std::cout << globalInt << std::endl;      // 0
        std::cout << staticInt << std::endl;      // 0
    
        return 0;
    }
    There's a few more cases I see though:

    Code:
    #include <iostream>
    
    struct WrappedInt
    {
        int mX;
    };
    
    int globalIntArray[5];
    
    WrappedInt globalWrappedInt;
    
    int main()
    {
        static int staticIntArray[5];
        static WrappedInt staticWrappedInt;
    
        std::cout << globalIntArray[0] << std::endl;   // ???
        std::cout << globalWrappedInt.mX << std::endl; // ???
        std::cout << staticIntArray[0] << std::endl;   // ???
        std::cout << staticWrappedInt.mX << std::endl; // ???
        std::cout << *(new int()) << std::endl;        // ???
    
        return 0;
    }

  3. #18
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,673
    Code:
        std::cout << int() << std::endl;          // 0
    My interpretation of the rules has been that you need to supply an expression. I'm not sure why you ignored "zero taken as a constant integral expression [...]".
    Further 8.5.8 and 8.5.9 say:
    8 An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
    [ Note: since () is not permitted by the syntax for initializer,
    X a();
    is not the declaration of an object of class X, but the declaration of a function taking no argument and returning an X.
    The form () is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2). —end note ]
    9 If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array
    thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying class type shall
    have a user-declared default constructor. Otherwise, if no initializer is specified for a non-static object, the object and
    its subobjects, if any, have an indeterminate initial value97);
    if the object or any of its subobjects are of const-qualified
    type, the program is ill-formed.

    97) This does not apply to aggregate objects with automatic storage duration initialized with an incomplete brace-enclosed initializer-list; see 8.5.1.
    Rules 8 and 9 may appear to conflict with each other but I think the difference is this:
    Code:
    #include <iostream>
    
    int f(int x);
    
    int f(int x = int()) // defined -- used as an initializer
    {
       return x;
    }
    
    int main()
    {
       // int x(); //used as a definition--indeterminate initial value
       std::cout<<f()<<std::endl;
    }
    
    #if 0
    My output:
    0
    #endif
    More importantly than the output, I didn't get any warnings or errors on compile, so I must be using int() as it was meant to be. int x(); does not initialize because it is not initialization but a definition. I blame myself for this confusion though so I am sorry.

  4. #19
    Registered User
    Join Date
    Jun 2005
    Posts
    6,266
    Quote Originally Posted by whiteflags View Post
    int x(); does not initialize because it is not initialization but a definition.
    int x(); is a declaration of a function named x() that returns int and takes zero arguments.
    Right 98% of the time, and don't care about the other 3%.

  5. #20
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,673
    But then, int isn't a class, so I don't think that really applies.

  6. #21
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,660
    Quote Originally Posted by whiteflags
    But then, int isn't a class, so I don't think that really applies.
    You don't think what really applies?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #22
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    It's important to distinguish between value-initialization, zero-initialization, default-initialization, and no initialization. Yes, C++ is weird here. C++0x's unified initializers ought to improve the situation.

    First, the plain definitions, paraphrased from the standard. (8.5 [dcl.init]p5):

    Zero-initialize:
    - Scalars (pretty much everything built-in, and pointers): initialize to zero or null.
    - Compounds (arrays, structs, classes): recursively zero-initialize each part.
    - Unions: zero-initialize the first member.

    Default-initialize:
    - Arrays: recursively default-initialize each element.
    - PODs: zero-initialize.
    - Non-PODs: call default constructor, or error if there is none.

    Value-initialize:
    - Classes with custom constructors: call default constructor, or error if there is none.
    - Other classes and arrays: recursively value-initialize each element.
    - Others: zero-initialize.

    POD: roughly: scalars, classes that consist only of PODs and have no bases, virtual functions, or special member functions, arrays of PODs.


    With these definitions, we can now look at when each kind of initialization is performed.

    1) Things with static storage duration (globals, static members, static locals) are zero-initialized before anything else happens.
    2) If the object has an initializer of the form "()", it is value-initialized. (Note: 'int x();' is a function, but you can use the pseudo-constructor form 'int()' to create a value-initialized int temporary, or 'new int()' to allocate a value-initialized int on the heap.)
    3) If the object has no initializer ('T obj;', but also 'new T'): non-PODs are default-initialized; otherwise, no initialization is done.


    As you can see, the really nasty part is that default-construction claims to zero-initialize PODs, but there is no context in which PODs are ever default-initialized! ([class.init]p1 claims that there is, but it's wrong. See CWG DR 510.)
    C++0x makes this part of the standard much clearer by changing default-initialization to mean no initialization for PODs, and removing the POD exception from all places that reference it.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #23
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,673
    Quote Originally Posted by laserlight View Post
    You don't think what really applies?
    Sorry, since int isn't a class

    int x();

    is not a function returning int which has no arguments.

  9. #24
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Quote Originally Posted by whiteflags View Post
    Sorry, since int isn't a class

    int x();

    is not a function returning int which has no arguments.
    Yes, it is. The type kind is irrelevant here, because this is a syntactic ambiguity.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #25
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,660
    The note reads:
    since () is not permitted by the syntax for initializer,
    X a();
    is not the declaration of an object of class X, but the declaration of a function taking no argument and returning an X.
    The note could have stated this instead:
    since () is not permitted by the syntax for initializer,
    int a();
    is not the declaration of an object of type int, but the declaration of a function taking no argument and returning an int.
    The point is, "() is not permitted by the syntax for initializer", so there are certain ramifications. Just because one of the ramifications is arguably not included in the elaboration does not mean that it does not apply.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Page 2 of 2 FirstFirst 12
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, 06:34 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21