0
#include <iostream>

using namespace std;

struct A
{
    A()
        : _p(new int(1))
    {}

    ~A()
    {
        *_p = 0;

        delete _p;
        _p = nullptr;
    }

    int* _p;
};

int main()
{
    //
    // Let r_to_a reference to a temporary object
    //
    A& r_to_a = A();

    //
    // Is r_to_a still valid now?
    //
    cout << *r_to_a._p << endl; // Output : 1 instead of a run-time error
}

As I have been knowing, non-const referencing to a temporary object is ill-formed. However, the code above shows it seems legal in C++. Why?

My compiler is VC++ 2013.

xmllmx
  • 39,765
  • 26
  • 162
  • 323

1 Answers1

2

The code does not really show that it is legal in C++. It simply shows that your compiler supports a non-standard compiler extension. You have to consult your compiler docs to find out whether the lifetime of the temporary is extended. Your experiment appears to show that it is extended.

Nevertheless, your code is ill-formed in standard C++. If you disable compiler extensions in that compiler by using /Za option, it will also refuse to accept your code:

error C2440: 'initializing' : cannot convert from 'A' to 'A &'

Alternatively, to avoid using /Za (which is apparently broken) you can do

#pragma warning(error : 4239)

or change the corresponding project setting under C/C++ -> Advanced -> Treat Specific Warnings As Errors to prohibit this specific functionality in a more targeted manner.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • 1
    It will also fail to compile its own headers when you explicitly disable extensions ;-) – rubenvb Nov 02 '13 at 08:03
  • 1
    @rubenvb: I was under impression that it might fail to compile WindowsAPI headers with extensions disabled. But standard headers should be compilable. (Correct me if I'm wrong.) – AnT stands with Russia Nov 02 '13 at 08:15
  • @AndreyT: I'm sure I remember some gigantic row about that: at some point the library implementers for MSVC officially declared that they don't support `/Za`. Perhaps because there was a bug in `/Za` mode? I was under the impression that this included the standard libraries, but I don't remember the details (or even what header it was), and it's possible that it has been fixed since then. – Steve Jessop Nov 02 '13 at 11:02
  • It's just broken. See [here](http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-June/021886.html) for STL's (the initials, not the acronym) official message to the Clang devs who apparently used the option to force standards enforcement. – rubenvb Nov 02 '13 at 13:37
  • @rubenvb: yes, I think that's the one. Note that /W4 "warns about most of the extensions", which I think is a way of saying "the compiler team has no plans to ship a conforming implementation so we, the library team, wash our hands of them" ;-) – Steve Jessop Nov 02 '13 at 15:55
  • @rubenvb: OK, I see. In that case `#pragma warning(error : 4239)` might be a better idea for MSVC++ compiler. – AnT stands with Russia Nov 02 '13 at 16:22