0

Consider this code :

int main()
{
    int i(6); //this will result in i==6,but consider next initializations

    int j(int()); 

    T * p2 = new T(); 
}

I find that the value of j is 1, but this should be 0 because int() is a temporary with value equal to 0.

Also, the syntax for the new operator is new typename, but here T() will be a temporary object instead of a type name.

Cactus Golov
  • 3,474
  • 1
  • 21
  • 41
T.J.
  • 1,466
  • 3
  • 19
  • 35
  • 1
    You're confused, `new T()` does dynamically allocate a `T` object and value initialize it, it does not create a temporary. What are you actually trying to do. – Ben Voigt Feb 19 '12 at 07:06
  • This should be closed, right now there's no question, and if a question is added, it'll be a dupe of either the links in Nawaz's answer or else http://stackoverflow.com/questions/2671532/non-copyable-objects-and-value-initialization-g-vs-msvc and http://stackoverflow.com/questions/6298001/value-initializing-an-automatic-object – Ben Voigt Feb 19 '12 at 07:08
  • In fact, TJ just asked one of those questions two hours ago: http://stackoverflow.com/questions/9346687/value-initialization-for-automatic-variables **Next time read the question links left in the comments, TJ!** – Ben Voigt Feb 19 '12 at 07:08

2 Answers2

4
int j(int()); 

This doesn't declare an object. Instead it declares a function which takes a function as argument, and returns int. The type of the function which it takes as argument is this :

 typedef int (*funtype)();

That, is, a function which returns int, and takes nothing as argument.

The parsing of such a declaration is commonly known as:


And in the new syntax, T() doesn't create a temporary object. That is not how it is to be seen. Instead, you've to look at the entire expression new T() which first allocates memory for an object of type T, and then construct the object in that memory. If T is a user-defined type, then it calls the default constructor to construct the object, after allocating the memory.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 4
    And the fix is to either use extra parenthesis to make it an invalid function declaration: `int j((int()));`, or avoid the syntax: `int j = int();`. – GManNickG Feb 19 '12 at 06:56
  • @nawaz: and what about secoond question – T.J. Feb 19 '12 at 07:03
1

Also syntax for new operator is typename *variable_name = new typename, but here T() will be a temporary object but not type name.

Similarly to the Most Vexing Parse, T() has different meanings depending on context. It does not always produce a temporary, but generally initializes some new anonymous object or subobject. The object might be

  • a temporary if T() is in an expression,
  • base subobject if T() appears before the body in a constructor, or
  • the referent of the pointer if T() appears after new. Note that the pointer has a name, but the object is anonymous.

new T and new T() do slightly different things: for some types, new T leaves values uninitialized. (The official term is default-initialization.) There is no corresponding grammatical construct for base subobjects or temporaries: base subobjects are default-initialized by omitting the initializer, and temporaries are not allowed to be default-initialized. The difference is minor, since in all these cases a constructor will be called if you defined one, and a constructor should always be defined, and it should always initialize all members. Exceptions are fundamental types such as int and simple structures like std::array<char, 1000>.

To be on the safe side, it's best to avoid new T in favor of new T() just to make sure that things are nicely zeroed out in the absence of a constructor.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421