tags:

views:

188

answers:

5

In the following code sample, do the C++ standard guarantee that '++i' is evaluated after the memory allocation (call to operator new) but before the call to X’s constructor?

new X( ++i )
+1  A: 

++i should be performed before allocation AND call.

EDIT: (and I may have answered a bit too quickly)

Julian Aubourg
Do you have any evidence for this?
S.Lott
Hmmm... now that I think about it, it's equivalent to ((X*)malloc(sizeof(X)))->X(++i) somehow and I'm not that sure anymore :/. I guess the compiler "should" make it equivalent to newFunction(++i) but I may have answered a bit hastily.
Julian Aubourg
In C, the answer would be yes; there is a sequence point before a function call and all side-effects in evaluating its arguments must be complete before the function is called. I would expect the same to hold in C++.
Jonathan Leffler
The selected answer is clear that the ++i is not necessarily performed before (or after) the allocation; I think it is clear it is performed before the constructor is called.
Jonathan Leffler
Yep, I was wrong... and hasty :)
Julian Aubourg
still..i vote u up..for the try..!
Warrior
+2  A: 

In a word, no.

There is no sequence point between "new" and "++i"

zildjohn01
you are right too..!
Warrior
+4  A: 

In general, the C++ compiler is free to re-order function parameters as long as it does not alter the meaning.

See Martin's answer here: http://stackoverflow.com/questions/367633/what-are-all-the-common-undefined-behaviour-that-c-programmer-should-know-about

There are actually 2 function calls going on here under the hood.

  1. operator new
  2. constructor call for X

Even though it's two separate calls, I do not believe there is a sequence point between these two operations. Wikipedia appears to support this point. Therefore the Compiler is free to reorder evaluation as it sees fit.

JaredPar
+1  A: 

new X( ++i )

The syntax for new operator wrt C++ standard:

[::] "new" ["(" expression-list ")"] {new-type-id | "(" type-id ")"} ["(" expression-list ")"]

So,

  1. Allocates memory for object X.
  2. The expression list will evaluated to be passed into the constructor of the object allocated.

so, we can sure that, ++i will be evaluated, before the constructor of Object X is invoked.

Cheers..

Warrior
Well, this tells you in which order it will be PARSED. Not in which order it will be executed. Though it is certain ++i will be called before the constructore no matter what).
Julian Aubourg
+12  A: 

From my copy of n2798:

5.3.4 New

21 Whether the allocation function is called before evaluating the constructor arguments or after evaluating the constructor arguments but before entering the constructor is unspecified. It is also unspecified whether the arguments to a constructor are evaluated if the allocation function returns the null pointer or exits using an exception.

Read in conjunction with (to avoid ambiguities):

5.3.4 New

8 A new-expression obtains storage for the object by calling an allocation function (3.7.4.1). If the newexpression terminates by throwing an exception, it may release storage by calling a deallocation function (3.7.4.2). If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete. If the allocated type is an array type, the allocation function’s name is operator new[] and the deallocation function’s name is operator delete[]. [...]

This pretty much answers the question. The answer is 'No'.

dirkgently
Yes, it's quite clear :)
Julian Aubourg
That was quick. Thanks!
Would I be right in interpreting that indeterminacy to only extend to the allocation function - the arguments are fully evaluated before the constructor proper is called, isn't it?
Jonathan Leffler
Yes -- that holds true for any function, doesn't it? The only caveat is -- the order in which parameters are evaluated is *unspecified*.
dirkgently
+1, very clear and direct!
Johannes Schaub - litb