473,508 Members | 2,330 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C4239 - why here?

Hi all!

I understand the rationale behind the warning 4239 (I think :-))
(warning C4239: nonstandard extension used : 'argument' : conversion from X
to Y A reference that is not to 'const' cannot be bound to a non-lvalue;
assigment operator takes a reference to non-const)

However, in this situation:

void F(X& x)

I get it for code like this:

F(X());

And I find it perfectly fine. So I have to use pragma's or split this in two
lines like this:
{ X x;
F(x); }

(With brackets, x gest destroyed immediately after the call; without, it
goes out of scope later, which sometimes isn't good; but OK, this is not my
man point)

Anyhow... Yuck!

Anybody has a comment on this isue? (Especially this: what "const" has to do
with anything here!?)

Goran.
Nov 17 '05 #1
4 3296
Goran Pusic wrote:
Hi all!

I understand the rationale behind the warning 4239 (I think :-))
(warning C4239: nonstandard extension used : 'argument' : conversion from X
to Y A reference that is not to 'const' cannot be bound to a non-lvalue;
assigment operator takes a reference to non-const)

However, in this situation:

void F(X& x)

I get it for code like this:

F(X());

And I find it perfectly fine. So I have to use pragma's or split this in two
lines like this:
{ X x;
F(x); }

(With brackets, x gest destroyed immediately after the call; without, it
goes out of scope later, which sometimes isn't good; but OK, this is not my
man point)

Anyhow... Yuck!

Anybody has a comment on this isue? (Especially this: what "const" has to do
with anything here!?)


Basically, there is a rule that a non-const reference cannot bind to an
rvalue (such as a temporary). e.g.

int i;
int*& aref = &i; //attempting to bind to an rvalue
int& bref = 5; //again, binding to an rvalue
and your example:
X& x = X(); //binding to an rvalue.

Microsoft just gives a warning, though most compilers will refuse to
compile the code entirely.

The reason for the rule is to prevent the loss of modifications to
variables. For example:

void f(int& i)
{
i = 10;
}

double d = 0;
f(d);
//would you expect d to be 10?

Were the binding allowed, d would be converted to a temporary int, and f
would modify that temporary int, leaving d unchanged.

However, there isn't really a good reason why the binding shouldn't be
allowed when you have an exact type match (no conversions required), as
in your X example, but I think it was decided way back that the special
case wasn't really worth it, given the simple workaround.

Tom
Nov 17 '05 #2
> void f(int& i)
{
i = 10;
}

double d = 0;
f(d);
//would you expect d to be 10?


Yes, I see. In fact, i would expect the compiler to refuse this outright, it
just makes no sense at all! Using intrinsic type promotions on references
like this, tsk, tsk, naughty compiler... Pascal doesn't allow this! Does C#?
I hope not :-))

But, that's not my situation. I have X as a "polymorphic worker class", and
it may or not change inside X, I don't care. I just want to it passed to F
to get polymorphic behaviour in F depending on the calling context).
Sort-of:
BaseX
{ virtual f() }
X1:BaseX { overridden virtual F() }
X2, X3...
and then F(BaseX&) gets called like this: F(X1(params)), F(X2(params)),
F(X3(params)) etc...

Goran.
Nov 17 '05 #3
On Fri, 23 Sep 2005 13:48:01 +0200, "Goran Pusic" <go*********@yahoo.com>
wrote:
But, that's not my situation. I have X as a "polymorphic worker class", and
it may or not change inside X, I don't care. I just want to it passed to F
to get polymorphic behaviour in F depending on the calling context).
Sort-of:
BaseX
{ virtual f() }
X1:BaseX { overridden virtual F() }
X2, X3...
and then F(BaseX&) gets called like this: F(X1(params)), F(X2(params)),
F(X3(params)) etc...


I talked about this problem here and in the message referenced from 1997:

http://groups.google.com/group/micro...2c9910ccae9bfd

The solution (kludge) I settled on was to make F take a spuriously const
X1&, which is fine unless the class stores a reference or pointer to the
object. The problem with a const X& parameter then is that it's very easy
to slip up and pass a temporary, which will be destroyed at the end of the
expression containing the function call, long before the class has finished
using it.

I once posted this as an example of a sort of built-in joke concerning the
whole rvalue/lvalue/reference behavior:

*****

http://groups.google.com/groups?selm...m7p6%404ax.com

struct X
{
};

void g(X&);

void f()
{
X() = X();

g(X() = X());

g(X()); // No good
}

Note that above, the result of assigning one rvalue to another rvalue
is a modifiable lvalue. :)

*****

The difference between the rvalues produced by X() and int() is that the
former has member functions you can call on it, and you're allowed to call
them, including the assignment operator, which by default returns a
reference to the object assigned.

--
Doug Harrison
VC++ MVP
Nov 17 '05 #4
Goran Pusic wrote:
void f(int& i)
{
i = 10;
}

double d = 0;
f(d);
//would you expect d to be 10?

Yes, I see. In fact, i would expect the compiler to refuse this outright, it
just makes no sense at all! Using intrinsic type promotions on references
like this, tsk, tsk, naughty compiler... Pascal doesn't allow this! Does C#?
I hope not :-))


Well, VC++ does at least give a diagnostic to indicate that the code has
an error - the code is "ill-formed" C++, and VC++ is reporting that fact.
But, that's not my situation. I have X as a "polymorphic worker class", and
it may or not change inside X, I don't care. I just want to it passed to F
to get polymorphic behaviour in F depending on the calling context).
Sort-of:
BaseX
{ virtual f() }
X1:BaseX { overridden virtual F() }
X2, X3...
and then F(BaseX&) gets called like this: F(X1(params)), F(X2(params)),
F(X3(params)) etc...


Perhaps F should take a const reference and f() should be a const
member? Alternatively, there is this workaround that must be used with care:

template <class T>
inline T& ref_from_temp(T const& t)
{
return const_cast<T&>(t);
}

F(ref_from_temp(X1(params)));

Tom
Nov 17 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
1408
by: manuel | last post by:
In the sample below, the foo function modify the b list, but I think it should modify only c, not b! It work correctly if if b is one dimension list instead two. def foo(aList): print "use...
2
1515
by: ariza | last post by:
greetings. it seems that the attribute site.here, of the site module, has vanished in python 2.4. up until python 2.3, site.here seemed (to me at least) a convenient way to get the complete path to...
15
2065
by: DavidS | last post by:
Have Visual Studio.NET installed on MS 2000 Professional OS laptop. No issue ever with web development and SQL connections. Purchased new laptop with XP Professional SP2!!!!!!!! & Visual...
22
2169
by: Rob R. Ainscough | last post by:
Sorry to hear about the job cuts and Oracle now out sourcing to India. Rob.
0
1313
by: Ramprasad | last post by:
Life is Different here, sky has no limit but you must grip it with this website, your Mirror of mind are present there. Whatever you want related to your everyday life, it can present or give...
1
1592
by: leighahh | last post by:
Hi everyone i was wondering if there was a way to turn this code that is css into HTML <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"...
2
3363
by: dibblm | last post by:
I'll start this hopefully simple and add code where needed or requested. Im using a combobox that bound to a DataSet. The Dataset retreives it's values from SQL. I can retreive the values...
0
7233
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7342
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
7067
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7505
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5650
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5060
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4729
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3201
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
440
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.