Hello everyone,


I am debugging MSDN code from,

http://msdn2.microsoft.com/en-us/library/0eestyah(VS.80).aspx

here is my output,

1>main.cpp
1>d:\visual studio 2008\projects\test_c4350\test_c4350\main.cpp(21) :
warning C4350: behavior change: 'B::B(A)' called instead of 'B::B(B &)'
1> d:\visual studio 2008\projects\test_c4350\test_c4350\main.cpp(13)
: see declaration of 'B::B'
1> d:\visual studio 2008\projects\test_c4350\test_c4350\main.cpp(9) :
see declaration of 'B::B'
1> A non-const reference may only be bound to an lvalue

I do not quite understand why there is a warning A non-const reference may
only be bound to an lvalue and 'B::B(A)' called instead of 'B::B(B &)'? Could
anyone give some descriptions please?


thanks in advance,
George

Re: A non-const reference may only be bound to an lvalue? by Carl

Carl
Thu Dec 13 22:18:35 PST 2007

George wrote:
> Hello everyone,
>
>
> I am debugging MSDN code from,
>
> http://msdn2.microsoft.com/en-us/library/0eestyah(VS.80).aspx
>
> here is my output,
>
> 1>main.cpp
> 1>d:\visual studio 2008\projects\test_c4350\test_c4350\main.cpp(21) :
> warning C4350: behavior change: 'B::B(A)' called instead of 'B::B(B
> &)' 1> d:\visual studio
> 2008\projects\test_c4350\test_c4350\main.cpp(13)
>> see declaration of 'B::B'
> 1> d:\visual studio
> 2008\projects\test_c4350\test_c4350\main.cpp(9) : see declaration of
> 'B::B' 1> A non-const reference may only be bound to an lvalue
>
> I do not quite understand why there is a warning A non-const
> reference may only be bound to an lvalue and 'B::B(A)' called instead
> of 'B::B(B &)'? Could anyone give some descriptions please?

Class B has two constructors: B::B(B&) and B::B(A), and it also has a
conversion operator B::operator A().

In the example, an object of class 'B' named 'ap' is created and initialized
with the results of a function call that returns an instance of 'B' by
value.

That returned instance of B is not an lvalue - it's a temporary rvalue.

The warning is telling you that under VC++ 7.1 (and later), this results in
this calling sequence:

source()
A::A() // create the return value for source
B::B(A) // convert it from an A to a temporary B
B::operator A() // convert that temporary B a temporary A
B::B(A) // initialize ap with that temporary A

... while under VC7 (and before), the following sequence would have
occurred:

source()
A::A()
B::B(A)
B::B(B&) // initialize ap with the temporary instance of B

This change is required by the C++ standard which specifies that a non-const
reference (such as the B& parameter in the B::B(B&) constructor) can only
bind to an lvalue. Since the temporary B that's returned by source() is not
an lvalue, this constructor cannot be used, so the compiler is forced to use
the B::B(A) constructor, which it can use by virtue of B::operator A().

Check out this forum thread, where Tom Widmer gave a good explanation of the
rationale for this rule:

http://www.thescripts.com/forum/thread285370.html

-cd



Re: A non-const reference may only be bound to an lvalue? by George

George
Fri Dec 14 02:23:01 PST 2007

Thanks cd,


Why,

> That returned instance of B is not an lvalue - it's a temporary rvalue.?

I think lvalue is something we can address and rvalue is something we can
not address. The reurn instance of B is a temporary object, I think an object
is addressable and should be lvalue?

Please feel free to correct me.


regards,
George

"Carl Daniel [VC++ MVP]" wrote:

> George wrote:
> > Hello everyone,
> >
> >
> > I am debugging MSDN code from,
> >
> > http://msdn2.microsoft.com/en-us/library/0eestyah(VS.80).aspx
> >
> > here is my output,
> >
> > 1>main.cpp
> > 1>d:\visual studio 2008\projects\test_c4350\test_c4350\main.cpp(21) :
> > warning C4350: behavior change: 'B::B(A)' called instead of 'B::B(B
> > &)' 1> d:\visual studio
> > 2008\projects\test_c4350\test_c4350\main.cpp(13)
> >> see declaration of 'B::B'
> > 1> d:\visual studio
> > 2008\projects\test_c4350\test_c4350\main.cpp(9) : see declaration of
> > 'B::B' 1> A non-const reference may only be bound to an lvalue
> >
> > I do not quite understand why there is a warning A non-const
> > reference may only be bound to an lvalue and 'B::B(A)' called instead
> > of 'B::B(B &)'? Could anyone give some descriptions please?
>
> Class B has two constructors: B::B(B&) and B::B(A), and it also has a
> conversion operator B::operator A().
>
> In the example, an object of class 'B' named 'ap' is created and initialized
> with the results of a function call that returns an instance of 'B' by
> value.
>
> That returned instance of B is not an lvalue - it's a temporary rvalue.
>
> The warning is telling you that under VC++ 7.1 (and later), this results in
> this calling sequence:
>
> source()
> A::A() // create the return value for source
> B::B(A) // convert it from an A to a temporary B
> B::operator A() // convert that temporary B a temporary A
> B::B(A) // initialize ap with that temporary A
>
> .... while under VC7 (and before), the following sequence would have
> occurred:
>
> source()
> A::A()
> B::B(A)
> B::B(B&) // initialize ap with the temporary instance of B
>
> This change is required by the C++ standard which specifies that a non-const
> reference (such as the B& parameter in the B::B(B&) constructor) can only
> bind to an lvalue. Since the temporary B that's returned by source() is not
> an lvalue, this constructor cannot be used, so the compiler is forced to use
> the B::B(A) constructor, which it can use by virtue of B::operator A().
>
> Check out this forum thread, where Tom Widmer gave a good explanation of the
> rationale for this rule:
>
> http://www.thescripts.com/forum/thread285370.html
>
> -cd
>
>
>

Re: A non-const reference may only be bound to an lvalue? by Igor

Igor
Fri Dec 14 05:12:30 PST 2007

"George" <George@discussions.microsoft.com> wrote in message
news:7790CF47-E70E-4079-A7C9-6F2C2FF528D8@microsoft.com
> Why,
>
>> That returned instance of B is not an lvalue - it's a temporary
>> rvalue.?
>
> I think lvalue is something we can address and rvalue is something we
> can not address. The reurn instance of B is a temporary object, I
> think an object is addressable and should be lvalue?

No, it's not "addressable" and it's not an lvalue. Specifically, this
doesn't compile:

B* p = &( source() );

--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: A non-const reference may only be bound to an lvalue? by George

George
Fri Dec 14 05:40:03 PST 2007

Thanks Igor,


Your reply is very helpful. I have performed some further self-study. In my
understanding, rvalue could be in two cases,

1. constant;

2. temporary object (e.g. function return value if the return value is not a
reference -- this is my sample for source() function, right?).

Is my understanding correct?

Another question is, why currently the compiler does not allow binding a
non-const reference to an rvalue? What is the internal reason and
benefits/risks behind this rule?


regards,
George

"Igor Tandetnik" wrote:

> "George" <George@discussions.microsoft.com> wrote in message
> news:7790CF47-E70E-4079-A7C9-6F2C2FF528D8@microsoft.com
> > Why,
> >
> >> That returned instance of B is not an lvalue - it's a temporary
> >> rvalue.?
> >
> > I think lvalue is something we can address and rvalue is something we
> > can not address. The reurn instance of B is a temporary object, I
> > think an object is addressable and should be lvalue?
>
> No, it's not "addressable" and it's not an lvalue. Specifically, this
> doesn't compile:
>
> B* p = &( source() );
>
> --
> With best wishes,
> Igor Tandetnik
>
> With sufficient thrust, pigs fly just fine. However, this is not
> necessarily a good idea. It is hard to be sure where they are going to
> land, and it could be dangerous sitting under them as they fly
> overhead. -- RFC 1925
>
>
>

Re: A non-const reference may only be bound to an lvalue? by Igor

Igor
Fri Dec 14 05:56:53 PST 2007

"George" <George@discussions.microsoft.com> wrote in message
news:2AC35AF1-DD6E-4A7E-9B83-81203539F863@microsoft.com
> Your reply is very helpful. I have performed some further self-study.
> In my understanding, rvalue could be in two cases,
>
> 1. constant;
>
> 2. temporary object (e.g. function return value if the return value
> is not a reference -- this is my sample for source() function,
> right?).

Sounds about right.

> Another question is, why currently the compiler does not allow
> binding a non-const reference to an rvalue? What is the internal
> reason and benefits/risks behind this rule?

To avoid surprises like this:

void f(long& x) { x = 1; }

int y = 0;
f(y); // hypothetical, doesn't compile
assert(y == 1); // fails

If f(y) were allowed to compile, it would generate a temporary of type
long, and the function would modify that temporary, leaving the original
int variable unchanged.

It would also mean that a seemingly benign change in function
signature( from f(int&) to f(long&) ) may silently alter the behavior of
the program. As things stand now, such a change would lead to compiler
errors - much better than silent behavior change.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: A non-const reference may only be bound to an lvalue? by Doug

Doug
Fri Dec 14 09:40:43 PST 2007

On Fri, 14 Dec 2007 08:56:53 -0500, "Igor Tandetnik" <itandetnik@mvps.org>
wrote:

>To avoid surprises like this:
>
>void f(long& x) { x = 1; }
>
>int y = 0;
>f(y); // hypothetical, doesn't compile
>assert(y == 1); // fails
>
>If f(y) were allowed to compile, it would generate a temporary of type
>long, and the function would modify that temporary, leaving the original
>int variable unchanged.
>
>It would also mean that a seemingly benign change in function
>signature( from f(int&) to f(long&) ) may silently alter the behavior of
>the program. As things stand now, such a change would lead to compiler
>errors - much better than silent behavior change.

The thing is, that's got little to do with the typical desired usage, which
is to permit:

void f(X&);

void g()
{
f(X());
}

There are legitimate reasons to want to do that, but I've come to accept it
shouldn't be allowed for this reason. Suppose you have a class:

struct Y
{
// Lifetime of x must exceed object's use of it
explicit Y(X& x)
: m_x(x)
{
}

X& m_x;
};

Whether or not you agree with the design of the class, under the existing
rule, you can't get into trouble binding a temporary to m_x, at least not
easily. And when you really need to say f(X()), there's always lvalue_cast.

--
Doug Harrison
Visual C++ MVP

Re: A non-const reference may only be bound to an lvalue? by David

David
Fri Dec 14 10:02:20 PST 2007

Doug Harrison [MVP] wrote:
> The thing is, that's got little to do with the typical desired usage, which
> is to permit:
>
> void f(X&);
>
> void g()
> {
> f(X());
> }
>
> There are legitimate reasons to want to do that, but I've come to accept it
> shouldn't be allowed for this reason. Suppose you have a class:

Doug:

Yes, this is the kind of situation where this has bitten me. In my case,
X was a function object with some modifiable internal state that was
used in f, but was not needed in g after f returned. This was
cross-platform code (developed on VC7.1), and just one of the other
compilers we were using a few years ago would not accept it (now, I
think, most will not).

Of course it is easily fixed by doing

void g()
{
X x;
f(x);
}

--
David Wilkinson
Visual C++ MVP

Re: A non-const reference may only be bound to an lvalue? by Doug

Doug
Fri Dec 14 13:20:06 PST 2007

On Fri, 14 Dec 2007 13:02:20 -0500, David Wilkinson <no-reply@effisols.com>
wrote:

>Of course it is easily fixed by doing
>
>void g()
>{
> X x;
> f(x);
>}

Alternatively, you can use the lvalue_cast I mentioned and keep the
original syntax:

template<typename T>
inline T&
lvalue_cast(const T& rvalue)
{
return const_cast<T&>(rvalue);
}

void g()
{
f(lvalue_cast(X()));
}

Or for some X, you can use the "joke" I posted in the thread Carl linked
to:

f(X() = X()); // Not serious

Only in C++ could assigning one rvalue to another rvalue produce a
modifiable lvalue. (This is actually the default for class types.)

--
Doug Harrison
Visual C++ MVP

Re: A non-const reference may only be bound to an lvalue? by George

George
Sat Dec 15 06:23:03 PST 2007

Thanks Igor,


I have tested that the code even does not compile in Visual Studio 2008.

The error message is,

1>d:\visual studio 2008\projects\test_rvalue2\test_rvalue2\main.cpp(7) :
error C2664: 'f' : cannot convert parameter 1 from 'int' to 'long &'

I have a further question, why a const reference could be binded to a
rvalue? What is the internal reason from compiler and Spec point of view?

"Igor Tandetnik" wrote:

> > Another question is, why currently the compiler does not allow
> > binding a non-const reference to an rvalue? What is the internal
> > reason and benefits/risks behind this rule?
>
> To avoid surprises like this:
>
> void f(long& x) { x = 1; }
>
> int y = 0;
> f(y); // hypothetical, doesn't compile
> assert(y == 1); // fails
>
> If f(y) were allowed to compile, it would generate a temporary of type
> long, and the function would modify that temporary, leaving the original
> int variable unchanged.
>
> It would also mean that a seemingly benign change in function
> signature( from f(int&) to f(long&) ) may silently alter the behavior of
> the program. As things stand now, such a change would lead to compiler
> errors - much better than silent behavior change.
> --
> With best wishes,
> Igor Tandetnik
>
> With sufficient thrust, pigs fly just fine. However, this is not
> necessarily a good idea. It is hard to be sure where they are going to
> land, and it could be dangerous sitting under them as they fly
> overhead. -- RFC 1925
>
>
>


regards,
George

Re: A non-const reference may only be bound to an lvalue? by George

George
Sat Dec 15 06:30:01 PST 2007

Hi Doug,


To my surprise, I have tested that the following code can compile,

struct X {

};

void f(X& x) {};

void g()
{
f(X());
}

I think it breaks the rule that non-const reference parameter X& x can not
be binded to a rvalue (return of X(), which is a temporary object, i.e.
rvalue)? Any comments?

I am using Visual Studio 2008.

"Doug Harrison [MVP]" wrote:

> On Fri, 14 Dec 2007 08:56:53 -0500, "Igor Tandetnik" <itandetnik@mvps.org>
> wrote:
>
> >To avoid surprises like this:
> >
> >void f(long& x) { x = 1; }
> >
> >int y = 0;
> >f(y); // hypothetical, doesn't compile
> >assert(y == 1); // fails
> >
> >If f(y) were allowed to compile, it would generate a temporary of type
> >long, and the function would modify that temporary, leaving the original
> >int variable unchanged.
> >
> >It would also mean that a seemingly benign change in function
> >signature( from f(int&) to f(long&) ) may silently alter the behavior of
> >the program. As things stand now, such a change would lead to compiler
> >errors - much better than silent behavior change.
>
> The thing is, that's got little to do with the typical desired usage, which
> is to permit:
>
> void f(X&);
>
> void g()
> {
> f(X());
> }
>
> There are legitimate reasons to want to do that, but I've come to accept it
> shouldn't be allowed for this reason. Suppose you have a class:
>
> struct Y
> {
> // Lifetime of x must exceed object's use of it
> explicit Y(X& x)
> : m_x(x)
> {
> }
>
> X& m_x;
> };
>
> Whether or not you agree with the design of the class, under the existing
> rule, you can't get into trouble binding a temporary to m_x, at least not
> easily. And when you really need to say f(X()), there's always lvalue_cast.
>
> --
> Doug Harrison
> Visual C++ MVP
>


regards,
George

Re: A non-const reference may only be bound to an lvalue? by George

George
Sat Dec 15 06:33:00 PST 2007

Thanks David,


I agree and understand from you that from Spec we should not bind a rvalue
to a non-const reference, but in Visual Studio 2008, the following code can
compile and no warning messages. Any comments?

struct X {

};

void f(X& x) {};

void g()
{
f(X());
}



"David Wilkinson" wrote:

> Doug Harrison [MVP] wrote:
> > The thing is, that's got little to do with the typical desired usage, which
> > is to permit:
> >
> > void f(X&);
> >
> > void g()
> > {
> > f(X());
> > }
> >
> > There are legitimate reasons to want to do that, but I've come to accept it
> > shouldn't be allowed for this reason. Suppose you have a class:
>
> Doug:
>
> Yes, this is the kind of situation where this has bitten me. In my case,
> X was a function object with some modifiable internal state that was
> used in f, but was not needed in g after f returned. This was
> cross-platform code (developed on VC7.1), and just one of the other
> compilers we were using a few years ago would not accept it (now, I
> think, most will not).
>
> Of course it is easily fixed by doing
>
> void g()
> {
> X x;
> f(x);
> }
>
> --
> David Wilkinson
> Visual C++ MVP
>


regards,
George

Re: A non-const reference may only be bound to an lvalue? by George

George
Sat Dec 15 06:43:02 PST 2007

Hi Doug,


I do not quite understand why the following code can convert rvalue to
lvalue, could you provide more description please?

> template<typename T>
> inline T&
> lvalue_cast(const T& rvalue)
> {
> return const_cast<T&>(rvalue);
> }

"Doug Harrison [MVP]" wrote:

> On Fri, 14 Dec 2007 13:02:20 -0500, David Wilkinson <no-reply@effisols.com>
> wrote:
>
> >Of course it is easily fixed by doing
> >
> >void g()
> >{
> > X x;
> > f(x);
> >}
>
> Alternatively, you can use the lvalue_cast I mentioned and keep the
> original syntax:
>
> template<typename T>
> inline T&
> lvalue_cast(const T& rvalue)
> {
> return const_cast<T&>(rvalue);
> }
>
> void g()
> {
> f(lvalue_cast(X()));
> }
>
> Or for some X, you can use the "joke" I posted in the thread Carl linked
> to:
>
> f(X() = X()); // Not serious
>
> Only in C++ could assigning one rvalue to another rvalue produce a
> modifiable lvalue. (This is actually the default for class types.)
>
> --
> Doug Harrison
> Visual C++ MVP
>


regards,
George

Re: A non-const reference may only be bound to an lvalue? by Bo

Bo
Sat Dec 15 06:52:14 PST 2007

George wrote:
:: Thanks David,
::
::
:: I agree and understand from you that from Spec we should not bind
:: a rvalue to a non-const reference, but in Visual Studio 2008, the
:: following code can compile and no warning messages. Any comments?
::
:: struct X {
::
:: };
::
:: void f(X& x) {};
::
:: void g()
:: {
:: f(X());
:: }
::

This only works with the default compiler settings (for backward
compatibility to pre-standard C++). If you chose "Disable Language
Extensions" (option /Za), you will get

"error C2664: 'f' : cannot convert parameter 1 from 'X' to 'X &'
A non-const reference may only be bound to an lvalue"


Bo Persson



Re: A non-const reference may only be bound to an lvalue? by George

George
Sat Dec 15 07:02:00 PST 2007

Thanks Bo,


I have tested that you are correct. Just curious, what means disable
language extensions? Not allowing Visual Studio to extend language to
non-standard points (i.e. extend and Spec, and not 100% conforming to the
Spec)?

"Bo Persson" wrote:

> George wrote:
> :: Thanks David,
> ::
> ::
> :: I agree and understand from you that from Spec we should not bind
> :: a rvalue to a non-const reference, but in Visual Studio 2008, the
> :: following code can compile and no warning messages. Any comments?
> ::
> :: struct X {
> ::
> :: };
> ::
> :: void f(X& x) {};
> ::
> :: void g()
> :: {
> :: f(X());
> :: }
> ::
>
> This only works with the default compiler settings (for backward
> compatibility to pre-standard C++). If you chose "Disable Language
> Extensions" (option /Za), you will get
>
> "error C2664: 'f' : cannot convert parameter 1 from 'X' to 'X &'
> A non-const reference may only be bound to an lvalue"
>
>
> Bo Persson
>
>
>


regards,
George

Re: A non-const reference may only be bound to an lvalue? by Alex

Alex
Sat Dec 15 07:12:50 PST 2007

"Bo Persson" wrote:
> This only works with the default compiler settings (for
> backward compatibility to pre-standard C++). If you chose
> "Disable Language Extensions" (option /Za), you will get
>
> "error C2664: 'f' : cannot convert parameter 1 from 'X' to
> 'X &'
> A non-const reference may only be bound to an
> lvalue"
>

Also, if you set warning level 4 for the project, then
compiler produces the C4239 warning ("nonstandard extension
used").

Alex



Re: A non-const reference may only be bound to an lvalue? by Alex

Alex
Sat Dec 15 07:17:53 PST 2007

"George" wrote:
> [...] Just curious, what means disable
> language extensions? Not allowing Visual Studio to extend
> language to
> non-standard points (i.e. extend and Spec, and not 100%
> conforming to the
> Spec)?

George,

Why don't you just read the description of /Za switch in
MSDN? Accustom yourself to consult documentation every time
you're in doubt. Keep local MSDN reader opened all the time.

-------
"/Za, /Ze (Disable Language Extensions)"

The /Za compiler option emits an error for language
constructs that are not compatible with either ANSI C or
ANSI C++.
-------

Alex



Re: A non-const reference may only be bound to an lvalue? by Igor

Igor
Sat Dec 15 08:08:39 PST 2007

"George" <George@discussions.microsoft.com> wrote in message
news:B58BC723-F8FC-4EB4-99EA-74294E4C3272@microsoft.com
> I do not quite understand why the following code can convert rvalue to
> lvalue, could you provide more description please?
>
>> template<typename T>
>> inline T&
>> lvalue_cast(const T& rvalue)
>> {
>> return const_cast<T&>(rvalue);
>> }

It doesn't really convert anything, it just tricks the compiler into
forgetting that the original object was a temporary.

The compiler sees a function call taking a const reference: a temporary
can be bound to such a parameter. The compiler further sees the function
return a non-const reference: such a return value is an lvalue under C++
rules. The compiler doesn't trace through the body of the function to
determine that the parameter and the result actually refer to the same
object.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: A non-const reference may only be bound to an lvalue? by Igor

Igor
Sat Dec 15 08:17:56 PST 2007

"George" <George@discussions.microsoft.com> wrote in message
news:5DA42BF3-85FC-4B1F-B3FE-50EBB29BDFC3@microsoft.com
> I have tested that the code even does not compile in Visual Studio
> 2008.

Of course. Did you expect otherwise? My "hypothetical, doesn't compile"
comment should have tipped you off. Which part of it did you find
unclear?

> I have a further question, why a const reference could be binded to a
> rvalue? What is the internal reason from compiler and Spec point of
> view?

So that you could accept temporaries as parameters, of course. There has
to be _some_ way to do that.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: A non-const reference may only be bound to an lvalue? by Bo

Bo
Sat Dec 15 13:21:03 PST 2007

George wrote:
:: Thanks Bo,
::
::
:: I have tested that you are correct. Just curious, what means
:: disable language extensions? Not allowing Visual Studio to extend
:: language to non-standard points (i.e. extend and Spec, and not
:: 100% conforming to the Spec)?

Sort of, yes. Note that MS doesn't claim to be 100% conformant in any
mode, more like 98%.

Also, the "extensions" are not just extensions either, but is also
removing some parts of the language. It's more like adapting the
compiler to the code in windows.h, which doesn't compiler in /Za mode.


Bo Persson


::
:: "Bo Persson" wrote:
::
::: George wrote:
::::: Thanks David,
:::::
:::::
::::: I agree and understand from you that from Spec we should not
::::: bind a rvalue to a non-const reference, but in Visual Studio
::::: 2008, the following code can compile and no warning messages.
::::: Any comments?
:::::
::::: struct X {
:::::
::::: };
:::::
::::: void f(X& x) {};
:::::
::::: void g()
::::: {
::::: f(X());
::::: }
:::::
:::
::: This only works with the default compiler settings (for backward
::: compatibility to pre-standard C++). If you chose "Disable Language
::: Extensions" (option /Za), you will get
:::
::: "error C2664: 'f' : cannot convert parameter 1 from 'X' to 'X &'
::: A non-const reference may only be bound to an lvalue"
:::
:::
::: Bo Persson
:::
:::
:::
::
::
:: regards,
:: George




Re: A non-const reference may only be bound to an lvalue? by George

George
Sat Dec 15 22:12:00 PST 2007

I am clear now, thanks Igor!


regards,
George

"Igor Tandetnik" wrote:

> "George" <George@discussions.microsoft.com> wrote in message
> news:5DA42BF3-85FC-4B1F-B3FE-50EBB29BDFC3@microsoft.com
> > I have tested that the code even does not compile in Visual Studio
> > 2008.
>
> Of course. Did you expect otherwise? My "hypothetical, doesn't compile"
> comment should have tipped you off. Which part of it did you find
> unclear?
>
> > I have a further question, why a const reference could be binded to a
> > rvalue? What is the internal reason from compiler and Spec point of
> > view?
>
> So that you could accept temporaries as parameters, of course. There has
> to be _some_ way to do that.
> --
> With best wishes,
> Igor Tandetnik
>
> With sufficient thrust, pigs fly just fine. However, this is not
> necessarily a good idea. It is hard to be sure where they are going to
> land, and it could be dangerous sitting under them as they fly
> overhead. -- RFC 1925
>
>
>

Re: A non-const reference may only be bound to an lvalue? by George

George
Sat Dec 15 22:13:00 PST 2007

Sorry Alex, my weekend laziness. I will not be lazy next time. :-)


have a good weekend,
George

"Alex Blekhman" wrote:

> "George" wrote:
> > [...] Just curious, what means disable
> > language extensions? Not allowing Visual Studio to extend
> > language to
> > non-standard points (i.e. extend and Spec, and not 100%
> > conforming to the
> > Spec)?
>
> George,
>
> Why don't you just read the description of /Za switch in
> MSDN? Accustom yourself to consult documentation every time
> you're in doubt. Keep local MSDN reader opened all the time.
>
> -------
> "/Za, /Ze (Disable Language Extensions)"
>
> The /Za compiler option emits an error for language
> constructs that are not compatible with either ANSI C or
> ANSI C++.
> -------
>
> Alex
>
>
>

Re: A non-const reference may only be bound to an lvalue? by George

George
Sat Dec 15 22:17:00 PST 2007

Thanks Bo,


My question is answered.


regards,
George

"Bo Persson" wrote:

> George wrote:
> :: Thanks Bo,
> ::
> ::
> :: I have tested that you are correct. Just curious, what means
> :: disable language extensions? Not allowing Visual Studio to extend
> :: language to non-standard points (i.e. extend and Spec, and not
> :: 100% conforming to the Spec)?
>
> Sort of, yes. Note that MS doesn't claim to be 100% conformant in any
> mode, more like 98%.
>
> Also, the "extensions" are not just extensions either, but is also
> removing some parts of the language. It's more like adapting the
> compiler to the code in windows.h, which doesn't compiler in /Za mode.
>
>
> Bo Persson
>
>
> ::
> :: "Bo Persson" wrote:
> ::
> ::: George wrote:
> ::::: Thanks David,
> :::::
> :::::
> ::::: I agree and understand from you that from Spec we should not
> ::::: bind a rvalue to a non-const reference, but in Visual Studio
> ::::: 2008, the following code can compile and no warning messages.
> ::::: Any comments?
> :::::
> ::::: struct X {
> :::::
> ::::: };
> :::::
> ::::: void f(X& x) {};