2

Consider the following simple example:

struct A 
{
    int a;
    A(int b);
};

A *p;

A::A(int b) : a(b)
{
    p = this;
    std::cout << "A()" << std::endl; 
} 



int main()
{
    A(10); //What is it?
    std::cout << p -> a << std::endl; //10
}

I'm not sure that N3797::8.5 [dcl.init] may be applied here, because N3797::8.5/1 [dcl.init] says:

A declarator can specify an initial value for the identifier being declared. The identifier designates a variable being initialized

In the case there is no declartor. Which means that rule is not applicable.

If it's just a constructor call where does it specify int the Standard that expression of the form class-name(argument_list) allocate a fit amount of memory (What allocation function takes over that?) and initialize an object? I wish to acquire more details about how such expressions work?

Columbo
  • 60,038
  • 8
  • 155
  • 203

2 Answers2

2

Since you don't give a name, A(10) produces a temporary object of type A.

In the constructor of A, you assign the address of this temporary object to the pointer p. But the temporary object is destroyed at the end of the line A(10);. So you should not use the pointer p afterwards.

jdc
  • 319
  • 2
  • 5
  • Interesting. Can you provide a reference describing that it's temporary? –  Oct 12 '14 at 09:46
  • The reference is 12.2 [class.temporary]. It is obvious that an object without name can only be temporary. – jdc Oct 12 '14 at 10:04
  • It's important to note that the program will likely crash (maybe not on your platform but on some other...) – jdc Oct 12 '14 at 10:07
  • Could you clarify why? –  Oct 12 '14 at 10:10
  • Because in the expression `p -> a`, the pointer p is bound to an object that has been destroyed. This results in undefined behaviour. – jdc Oct 12 '14 at 10:28
  • See this discussion http://stackoverflow.com/questions/584824/guaranteed-lifetime-of-temporary-in-c – jdc Oct 12 '14 at 10:29
2
A(10);

This is a discarded-value expression. According to [expr.type.conv],

A simple-type-specifier (7.1.6.2) or typename-specifier (14.6) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).

The 'corresponding cast expression' is (A)10, which in turn is equivalent to static_cast<A>(10) ([expr.cast]/4), and the static_cast is defined as [expr.static.cast]/4:

Otherwise, an expression e can be explicitly converted to a type T using a static_cast of the form static_cast<T>(e) if the declaration T t(e); is well-formed, for some invented temporary variable t (8.5). The effect of such an explicit conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion.

And there you have your declarator.

Columbo
  • 60,038
  • 8
  • 155
  • 203