7

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 )

5 Answers5

12

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'.

Community
  • 1
  • 1
dirkgently
  • 108,024
  • 16
  • 131
  • 187
  • 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 Mar 15 '09 at 20:33
  • Yes -- that holds true for any function, doesn't it? The only caveat is -- the order in which parameters are evaluated is *unspecified*. – dirkgently Mar 15 '09 at 20:43
4

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: What are all the common undefined behaviours that a 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.

Community
  • 1
  • 1
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
2

In a word, no.

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

zildjohn01
  • 11,339
  • 6
  • 52
  • 58
1

++i should be performed before allocation AND call.

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

Julian Aubourg
  • 11,346
  • 1
  • 29
  • 29
  • Do you have any evidence for this? – S.Lott Mar 15 '09 at 19:43
  • 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 Mar 15 '09 at 19:48
  • 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 Mar 15 '09 at 19:59
  • 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 Mar 15 '09 at 20:34
1

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..

Vijay Angelo
  • 766
  • 6
  • 14
  • 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 Mar 15 '09 at 20:05