0

Trying to run this code, to see how anonymous object ctor/dctor are called in a single expression:

#include <math.h> 
#include <iostream>

using namespace std;

class Test {
    public:
        int mA = 0;

    Test() { 
        mA = 1000;
        cout << "ctor test" << endl;
    }
    ~Test() { 
        cout << "dctor test" << endl;    
    }
};

class MainPanel {
    public:
        Test mTest;

    MainPanel(Test *test) : mTest(*test) { 
        cout << "ctor main" << endl;
    }
    ~MainPanel() { 
        cout << "dctor main" << endl;    
    }
};

Test Crea() {
    cout << "crea" << endl;
    return Test();
}

int main() 
{   
    cout << "init " << endl;
    MainPanel mainPanel = MainPanel(&Crea());
    cout << mainPanel.mTest.mA << endl;
    cout << "end " << endl;
}

But (for example here with on g++) it deny this code: error: taking address of temporary [-fpermissive]

Instead, on msvc its seems permitted.

Why this could be "dangerous" to prevent it in first place?

markzzz
  • 47,390
  • 120
  • 299
  • 507
  • MSVC have an extension of the standard C++ that it allows using temporary objects (like the one returned by `Crea`) to be used in situations where standard C++ won't allow it. As for why it's not allowed, think about if you save the pointer, and want to dereference it later. What happens then when the temporary object is long gone? – Some programmer dude Feb 08 '18 at 08:31
  • 1
    I would ask why some compiler(s) allow it. – juanchopanza Feb 08 '18 at 08:32
  • `MainPanel(const Test& test)` would allow to use the temporary safely. – Jarod42 Feb 08 '18 at 09:34
  • 1
    The only difference is that g++ has the diagnostic on by default. MSVC has this as a level 4 warning ([C4238](https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4238)) and thus requires `/W4` to enable it. – Bo Persson Feb 08 '18 at 10:32

2 Answers2

2

It's deemed dangerous because of the risk for dangling pointers. Raw pointers have to no way to indicate how long lived the object they point to is going to be. It's non-standard behavior on MSVC's part.

To contrast with references, if you were to use them:

MainPanel(Test const&);
MainPanel(Test &&);

Both c'tors demonstrate exactly the value category of the object they expect to receive, and can even handle it accordingly. By making a copy or cannibalizing the source. Can't do that with pointers.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
1

Visual Studio allows it as a "nonstandard extension". See here.

The reason why it's not allowed in standard C++ is discussed here.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312