Value initialization using an empty pair of parentheses

This is a discussion on Value initialization using an empty pair of parentheses within the C++ Programming forums, part of the General Programming Boards category; I've read in a book that "we can value-initialize the elements by following the array size by an empty pair ...

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    10

    Question Value initialization using an empty pair of parentheses

    I've read in a book that "we can value-initialize the elements by following the array size by an empty pair of parentheses:"
    Code:
     int *pia = new int[10] ()
    Also the same book states that the following statements will generate different results:
    Code:
    int *pi = new int;         // pi points to an uninitialized int
    int *pi = new int();       // pi points to an int value-initialized to 0
    I've tested those with MinGW and I found no difference in using the pair of parentheses or not. In the case of the array, the elements will not be initialized and in the second case, pi will point to a 0 initialized int in both cases.

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,636
    >> I've read in a book that "we can value-initialize the elements by following the array size by an empty pair of parentheses:"

    Hmm. I've always thought that to be the case also, but GCC doesn't seem to do it properly, and now, well, I'm not so sure. I'll try to see if I can find it in the standard. In any case, keep in mind that assigning a raw pointer to the result of new is quite error prone - it should always be placed in an object with a destructor (or just use something like std::vector and be done with it).

  3. #3
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,403
    Quote Originally Posted by zephon View Post
    Code:
    int *pi = new int;         // pi points to an uninitialized int
    int *pi = new int();       // pi points to an int value-initialized to 0
    This is correct. The parenthesis instruct the compiler we want to initialize the pointer. This much we understand from user defined objects. If I define my own class and then want to initialize it, I may write something like and call the class default constructor:

    myClass* ptr = new myClass();

    For built-in types like int, the presence of parenthesis are a simple instruction for the compiler to initialize the pointer. Since we aren't providing any value, it will initialize it to zero. What I find extremely odd is that you are seeing also an initialization to 0 on int *pi = new int. Try the following code and post the results:

    Code:
    #include <iostream>
    
    int main() {
    
        int a = 13;
    
        int *pi = new int;
        int *pia = new int();
        int *pib = new int(a);
    
        std::cout << *pi << "   " << *pia << "    " << *pib;
    
    }
    It should output a random number, followed by 0, followed by 13.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    With MinGW 4.4.1 I see 0 0 13. Could be random luck or could be that the compiler doesn't bother to leave it uninitialized. (In practice I doubt one would ever allocate a single built-in type instance, and 99% of the time you wouldn't use array new either.)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,636
    >> What I find extremely odd is that you are seeing also an initialization to 0 on int *pi = new int.

    Maybe. But then again, zero is a pretty common value in memory, so that may just be the random value you get. The thing that bothers me is that the default initialization syntax doesn't work when I run it through GCC (the explicit initialization doesn't compile at all, either, though - perhaps I'm just overdue for an update?).

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,403
    Hmm... the compiler being benign, for a change?

    Seriously though, may be something somewhat recent. And something one can alter with some switch. I'm pretty sure I saw gcc with uninitialized pointers before and I seriously doubt it will work with -ansi -pedantic.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    10
    I also get 0 0 13 with MinGW and with Digital Mars compiler.

    For the array initialization I get the following compilation error with Digital Mars Compiler
    Code:
    int *px = new int[10]();
                          ^
    main.cpp(9) : Error: function expected
    So I guess this syntax is not standard. The book in which I've read about this is "C++ Primer" Fourth Edition.

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,403
    Try to add -ansi -pedantic to the compilation flags.

    As for the array. No. It doesn't work. I also have that book somewhere. I honestly don't remember they ever making such a crude mistake. The book is one of the most recommended books to learn C++. What's the page where you see that syntax for the array?

    EDIT: I flipped through and saw it. It's on page 134. And it works indeed. It value initializes the array elements to 0. Interesting. I do remember now seeing this before. What you cannot do however, contrary to non-array built in types is something like int *pia = new int[10] (3);. In this case, you'll need to explicitly initialize each member.

    Code:
    #include <iostream>
    
    int main() {
    
        int *pi = new int[10];
        int *pia = new int[10]();
    
        std::cout << pi[7] << "   " << pia[7];
    
    }
    Returns a random number followed by 0 on VC++ 2008.
    Last edited by Mario F.; 09-05-2009 at 08:48 AM.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  9. #9
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,403
    So, the fact the array is not working under MinGW is more troublesome.

    This is what I could found on the standard -- after only a quick perusal -- that, according to my interpretation, seems to indicate gcc is not following it:

    Quote Originally Posted by 5.3.4-15
    A new-expression that creates an object of type T initializes that object as follows:
    — If the new-initializer is omitted:
    — If T is a (possibly cv-qualified) non-POD class type (or array thereof), the object is default-
    initialized (8.5). If T is a const-qualified type, the underlying class type shall have a user-declared default constructor.
    — Otherwise, the object created has indeterminate value. If T is a const-qualified type, or a (possibly cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of const-qualified type, the program is ill-formed;
    — If the new-initializer is of the form (), the item is value-initialized (8.5);
    Quote Originally Posted by 8.5-5
    To zero-initialize an object of type T means:
    — if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
    — if T is a non-union class type, each nonstatic data member and each base-class subobject is zero- initialized;
    — if T is a union type, the object’s first named data member is zero-initialized;
    — if T is an array type, each element is zero-initialized;
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  10. #10
    Registered User
    Join Date
    Jan 2009
    Posts
    10
    With -ansi and -pedantic(MinGW) the value of *pi in
    Code:
    int *pi = new int;
    is 0. Then I've tried the following code
    Code:
    int main()
    {
        const int arr_size=2;
        int *px = new int[arr_size];
        for (size_t i  = 0; i < arr_size; ++i)
            std::cout << *(px + i) << std::endl;
        delete []px;
        return 0;
    }
    What I noticed is that for array sizes of one and two I always get 0 values in the array and for values bigger than two I get random values. Maybe the memory contains 0's at the adresses that the compiler choses for these smaller arrays.

    So this dynamic array initialisation is from standard. Then it means MinGW and Digital Mars are not quite standard conformant. Can somebody try this in GCC?

  11. #11
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,403
    Yes. It has to be a simple coincidence. But if:

    for array sizes of one and two I always get 0 values in the array and for values bigger than two I get random values
    Then you can always try this:

    Code:
    int main()
    {
    
        int *ptr = new int[120];
    
        const int arr_size=2;
        int *px = new int[arr_size];
        for (size_t i  = 0; i < arr_size; ++i)
            std::cout << *(px + i) << std::endl;
        delete []px;
        delete[] ptr;
    
        return 0;
    }
    Let's use up some of the heap prior to your array.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  12. #12
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Mario F. View Post
    So, the fact the array is not working under MinGW is more troublesome.

    This is what I could found on the standard -- after only a quick perusal -- that, according to my interpretation, seems to indicate gcc is not following it:
    — if T is an array type, each element is zero-initialized;
    Does that just mean an array on the stack, or also a pointer to an array on the heap?
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  13. #13
    Registered User
    Join Date
    Jan 2009
    Posts
    10
    Quote Originally Posted by Mario F. View Post

    Code:
    int main()
    {
    
        int *ptr = new int[120];
    
        const int arr_size=2;
        int *px = new int[arr_size];
        for (size_t i  = 0; i < arr_size; ++i)
            std::cout << *(px + i) << std::endl;
        delete []px;
        delete[] ptr;
    
        return 0;
    }
    I've tried it and it made no difference if the first array was bigger than 2. If the first array was of size 1 or 2, then the second one would get random values. So I guess my assumption was correct.

    Next I've tried this code:
    Code:
    int main()
    {
    
        const unsigned arr_size = 5;
        int *ptr[arr_size];
    
        for (size_t i=0; i < arr_size; ++i)
            ptr[i] = new int ();
    
        for (size_t i  = 0; i < arr_size; ++i)
            std::cout << *ptr[i] << std::endl;
    
        for (size_t i  = 0; i < arr_size; ++i)
            delete ptr[i];
    
        return 0;
    }
    Now here if I use new int() all ints will be 0 initialized while if the brackets were missing, the values will be random (only the first one will be 0, but the reason is similar to the case described above). So default value initialization is correct for single built-in types in MinGW. Only the array initialisation is not correct.
    Last edited by zephon; 09-05-2009 at 10:33 AM.

  14. #14
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,403
    Quote Originally Posted by cpjust View Post
    Does that just mean an array on the stack, or also a pointer to an array on the heap?
    Well, also an array on the heap, I'd think.
    The provision is established in 5.3.4-15 ("If the new-initializer is of the form (), the item is value-initialized (8.5)") and provides no exception for T being an array.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  15. #15
    Registered User
    Join Date
    Apr 2006
    Posts
    2,017
    Zero initializing when it's not required to isn't failing to follow the standard anyway.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

Page 1 of 3 123 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Regarding const array initialization
    By codegeru in forum C++ Programming
    Replies: 7
    Last Post: 07-19-2009, 10:55 AM
  2. Help with binary file c++
    By lucky_mutani in forum C++ Programming
    Replies: 4
    Last Post: 06-05-2009, 09:24 AM
  3. Polynomials and ADT's
    By Emeighty in forum C++ Programming
    Replies: 20
    Last Post: 08-19-2008, 08:32 AM
  4. Writing my own stl container
    By curos in forum C++ Programming
    Replies: 10
    Last Post: 12-18-2005, 03:33 AM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM

Tags for this Thread


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