Question

Can I access the member of an object if I create a temporary object by using class-type-name(parameters).member and presume that the constructor is done?

Consider the following example:

struct A
{
  enum status 
    { ERROR = -1, SUCCESS } state;
  A (int a) 
    : state(a > 0 ? SUCCESS : ERROR)
  {
    // do some stuff here
    // may change state
  }
};

int main (void)
{
  // Is this guaranteed to work?
  A::status S(A(5).state);
}

Is the constructor of A required to be done as soon as I access state?

Was it helpful?

Solution

Yes, the standard requires the implementation to perform all computations and side effects of the constructor of A before accessing state.


Reference:

The expression X(Y).Z is a Postfix expression as per 5.2.5/1 of C++11:

A postfix expression followed by a dot . or an arrow ->, optionally followed by the keyword template (14.2), and then followed by an id-expression, is a postfix expression.

The expression X(Y) is evaluated as per the same paragraph:

The postfix expression before the dot or arrow is evaluated.64

64: If the class member access expression is evaluated, the subexpression evaluation happens even if the result is unnecessary to determine the value of the entire postfix expression, for example if the id-expression denotes a static member.

That's where 1.9/14 applies:

Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated.

Therefore, the computations and side effects of X(Y) are done as soon as the dot operator is evaluated.

This expression however generates a fully constructed object X as per 5.2.3/1:

[...] the expression T(x1, x2, ...) is equivalent in effect to the declaration T t(x1, x2, ...); for some invented temporary variable t, with the result being the value of t as a prvalue.

and 12.2/3:

When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1, 12.8), it shall ensure that a constructor is called for the temporary object. [...] Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.

The standard requires the program to behave that way even if the acutal creation of the temporary object has not been performed (12.2/1):

Even when the creation of the temporary object is unevaluated (Clause 5) or otherwise avoided (12.8), all the semantic restrictions shall be respected as if the temporary object had been created and later destroyed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top