Question

I wrote the following code to test this:

struct X
{
   char* x;
   X()
   {
      x = new char('a');
   }
   ~X()
   {
      *x = 'b';
      delete x;
   }
};

void foo(const X& x)
{
}
void goo(X& x)
{
}

int main()
{
   foo(X());
   goo(X());
}

The destructors for the temporaries are called after both functions exit, but I thought you can only bind a temporary to a const reference. Why does goo work then?

Is it UB and MSVS is wrong, or is it ok?

Was it helpful?

Solution

It's illegal. A conforming implementation diagnoses it (i.e. it must at least warn), but MSVC++ allows it as an extension.

Or a bug if you're unkind, but IIRC the reason they still allow it is for long-lived legacy reasons: nominally to support code written for MSVC++ before C++ was standardized, but of course once you allow people to write this, they write it accidentally in new code too, so the legacy lives on. If it's deliberate then it's a (mis-)feature, not a bug, right? Anyway, a conforming implementation is required to diagnose ill-formed programs, so if you don't get a warning then the compiler isn't conforming.

OTHER TIPS

This is apparently a MS extension. In GCC 4.3.4, for instance, it fails to compile, with the following message:

prog.cpp: In function ‘int main()’:
prog.cpp:25: error: invalid initialization of non-const reference of type ‘X&’ from a temporary of type ‘X’
prog.cpp:18: error: in passing argument 1 of ‘void goo(X&)’
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top