-5
#include <conio.h>
#include <iostream>
using namespace std;
class A {
    int i;
public:
    A(int i) : i(i) { cout << i << endl; }
    A(const A &o) : i(o.i) { cout << i << endl; }
    ~A() { cout << i << endl; }
    friend A f(const A &, A, A *);
};
A f(const A &a, A b, A *c) { return *c; }
int main() { 
    f(1, A(2), &A(3));
}

output : 1 3 2 3 2 3 3 1
can someone please help me understand the reason behind the sequence of this output?

NatanC
  • 1
  • 1
  • 1
    You have undefined behviour (taking the address of a temporary object `&A(3)`, and then also dereferencing `c`, which is a dangling pointer in `f`) Better fix that first to avoid confusion. – juanchopanza Jun 30 '14 at 06:47
  • 1
    Taking the address of a temporary is undefined behaviour. Also, the evaluation of function parameters is unspecified behaviour. So this entire question is pretty flawed. – Rapptz Jun 30 '14 at 06:47
  • Well this is not really usefull, maybe create 3 objects that print differents symbols, so we can differenciate the three. –  Jun 30 '14 at 06:48
  • Is the intention to understand the construction order of the `A` objects when calling the function `f`? – Niall Jun 30 '14 at 06:52
  • yes! the intention is to understand the construction order of A. it is a question from an exam that i am having tomorrow.. – NatanC Jun 30 '14 at 06:55
  • 1
    Your **compiler** not [telling](http://coliru.stacked-crooked.com/a/7e453fef1aa871ba) [you](http://coliru.stacked-crooked.com/a/64a87a94ef04bfa8) [anything](http://coliru.stacked-crooked.com/a/08a177546c409ec6) ? :P – P0W Jun 30 '14 at 07:00
  • The evaluation order of function arguments is unspecified. But with undefined behaviour, anything goes, so the question is unanswerable unless you fix that. – juanchopanza Jun 30 '14 at 07:10

1 Answers1

0

The order of the evaluation of the function arguments is not defined; they can constructed in any order.

As a demonstration of this, here is some empirical evidence of this.

I've made minor modifications to print the output on a single line, also showing the construction ctor, copy construction copy and destruction dtor of each A and removing the undefined behaviour of caused by the use of &A(3).

#include <conio.h>
#include <iostream>
using namespace std;
class A {
    int i;
public:
    A(int i) : i(i) { cout << "ctor" << i << " "; }
    A(const A &o) : i(o.i) { cout << "copy" << i << " "; }
    ~A() { cout << "dtor" << i << " "; }
    friend A f(const A &, A, A *);
};
void f(const A &a, A b, A&& c) { ; }
int main() { 
    f(1, A(2), A(3));
}

Using GCC 4.9, I get ctor3 ctor2 ctor1 dtor1 dtor2 dtor3.

Using MSVC 2013.2, I get ctor1 ctor3 ctor2 dtor2 dtor3 dtor1.


As an aside; IRC, the order in which they are destructed is the reverse of the order in which they are constructed.

Niall
  • 30,036
  • 10
  • 99
  • 142