10

In Visual Studio 2012RC there are some non-standard extensions. For example this code compiles:

#include <string>

using namespace std;

void value(string& value)
{
    value = "some";
}

int main()
{
    value(string("nice"));
}

and get warning that it is non-standard extension. So, I want to understand, how it's real and how code transforms (rvalue-reference or const reference with const_cast)?

ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • 1
    AFAIK, Visual Studio 2010 (and maybe 2008) supports this behavior too. VC++ compiler permits to modify temporary objects. – flamingo Jul 16 '12 at 16:39
  • Note that this is poor style at best and bug-prone at worst (["Don't you care it's a temporary you are modifying?"](http://stackoverflow.com/a/1565811/768469)) – Nemo Jul 16 '12 at 16:59
  • 1
    @flamingo: Well, it has never been illegal to modify temporary objects in C++. It has always been allowed to call non-const *modifying* member functions of temporaries in C++. Yet, attaching non-const references using "direct" syntax is illegal. The former actually allows one to work around the latter, as shown in my answer. – AnT stands with Russia Jul 16 '12 at 17:04

3 Answers3

8

A temporary object of class type is still an object. It lives somewhere in memory, which means that there's nothing unusual in the compiler being able to attach a reference to it. At physical level whether it is a const reference or non-const reference makes no difference. In other words, in cases like that the language restriction is purely conceptual, artificial. The compiler simply ignores that restriction. There's no need to "transform" anything here. The reference is simply attached directly to the object, wherever that object happens to reside.

Basically, for a class that provides the outside word with access to the value of its this pointer (or with lvalue access to *this) the behavior can be immediately and easily simulated

struct S {
  S& get_lvalue() { return *this; }
};

void foo(S& s);
...

foo(S().get_lvalue());

The above code is perfectly legal and it works around the aforementioned restriction. You can think of MSVC++ behavior as being equivalent to this.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
3

Basically, VS will allocate the space somewhere and just let the reference point to it, as if it was a reference-to-const without the constness (or in C++11 an rvalue reference).

You can disable this behaviour with the /Za (disable language extensions) compiler switch under

Properties -> C/C++ -> Language

If I remember correctly.

Xeo
  • 129,499
  • 52
  • 291
  • 397
  • Thanks. Good answer. Accepted, but it`s bad to enable /ZA because any correct code will not compile (under C++11). – ForEveR Jul 16 '12 at 16:44
3

In standard C++ you cannot bind a temporary (rvalue / string("nice")) to a non-const reference (lvalue), but the microsoft compiler allows it. The warning is telling you that the code is compiling due to an extension and will not compile with any other compiler.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489