473,402 Members | 2,055 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,402 software developers and data experts.

Why this warning here?

Hi all!

I understand the rationale behind the VC++ 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.

Sep 23 '05 #1
7 4770

Goran wrote:
Hi all!
[snip]
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); }
[snip]
Anybody has a comment on this isue? (Especially this: what "const" has
to do with anything here!?)
The signature on F is an indication that F changes x, so x is a return
value.

F(X()) discards that return-value.

And this is what the warning is about.
Perhaps you should have declared F as F(X const& x)?
/Peter
Goran.


Sep 23 '05 #2
Goran wrote:
Hi all!

I understand the rationale behind the VC++ 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.


This is the problem: F accepts a non-const reference to a variable of
type X. So F may modify this parameter. However, the function call to F
passes a temporary as a parameter. So F's modifications would be to a
tempory that is then thrown away. So why call F? Or why does it accept
a parameter? Or why pass a tempory? Something doesn't add up here.

The most likely fix is that F does not modify x. So F's parameter
should be declared a const reference. If it does modify x, it should be
passed a non temporary X so that the caller will have the modified x.

Greg

Sep 23 '05 #3
> The signature on F is an indication that F changes x, so x is a return
value.


Yep that's a good reason the warning may be desirable. Not so in my
case

:-((

In my case, X is rather 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 F(X1(params)), F(X2(params)),
F(X3(params)) etc...

Sep 23 '05 #4

Goran wrote:
The signature on F is an indication that F changes x, so x is a return
value.
Yep that's a good reason the warning may be desirable. Not so in my
case

:-((


If that is the case, you could just write the code in two steps. Not a
big deal, is it? Anyway....
In my case, X is rather 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). If you don't care if the parameter gets changed, this is an indication
that there is something wrong with your design.

sort-of:
BaseX
{
virtual f()
}

X1:BaseX
{
overridden virtual F()
}
X2, X3...

and then F(BaseX&) gets called F(X1(params)), F(X2(params)),
F(X3(params)) etc...


This is perfectly feasible so long as the virtual functions are const.
This should be clear from the purpose of f.

/Peter

Sep 23 '05 #5

Goran wrote:
The signature on F is an indication that F changes x, so x is a return
value.


Yep that's a good reason the warning may be desirable. Not so in my
case

:-((

In my case, X is rather 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 F(X1(params)), F(X2(params)),
F(X3(params)) etc...


It's safe to assume that the caller of any function may want to know
which parameters may change and which will not. Or to put it another
way: which parameters are inputs, which are outputs and which are both.
The proper use of const here helps to provide the client with that kind
of information.

In this case it certainly sounds like the function call to F with the
temporary is not a mistake. So that means that there is no reason not
to declare F's parameter, x, const. F modifying x would then be a
legitimate error. What would be the point, given that x is not being
returned to the caller. Well, it could turn out that F is calling a non
const method of X's that does not actually modify the object. So
declaring that method in X const would resolve that error. And so on
and so forth.

The nice thing about maintaining const-correctness in a C++ program is
how constness cascades throughout the program. Fixing one const error
often requires other changes in order to restore the program to a
const-correct state. Some programmers are annoyed by this fact and will
go the other direction and declare const as seldom as possible. But
there is value in writing const-correct code. It is more than a mere
nuisance. For one, it helps prevents unintended or accidental changes.
It is also a way of documenting an API - of ensuring that a client
understands what calling a particular function may do.

Greg

Sep 23 '05 #6
> > In my case, X is rather 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). If you don't care if the parameter gets changed, this is an indication
that there is something wrong with your design.


Eh, easy to say... Actually, My X will change something else, that is
the point. I wantit (well, X1, X2, etc below) to act somewhere (not
really on itself, but on its members, and const-ness will propagate to
them). I want that F does what it does, including doing something
differently in different contexts, using X's polymorphism with f().

But, as you say, there's an easy workaround...

sort-of:
BaseX
{
virtual f()
}

X1:BaseX
{
overridden virtual f()
}
X2, X3...

and then F(BaseX&) gets called F(X1(params)), F(X2(params)),
F(X3(params)) etc...


Sep 23 '05 #7
> > In my case, X is rather 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). If you don't care if the parameter gets changed, this is an indication
that there is something wrong with your design.


Eh, easy to say... Actually, My X will change something else, that is
the point. I wantit (well, X1, X2, etc below) to act somewhere (not
really on itself, but on its members, and const-ness will propagate to
them). I want that F does what it does, including doing something
differently in different contexts, using X's polymorphism with f().

But, as you say, there's an easy workaround...

sort-of:
BaseX
{
virtual f()
}

X1:BaseX
{
overridden virtual f()
}
X2, X3...

and then F(BaseX&) gets called F(X1(params)), F(X2(params)),
F(X3(params)) etc...


Sep 23 '05 #8

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

Similar topics

1
by: None | last post by:
Hello, I am a total newbie to PHP and programming in general. I am playing around with a PHP / MySQL shopping cart script which I found at...
4
by: thule | last post by:
Okay, thanks to John (THANK YOU SO MUCH). I switched all my header files over to using the new Standard <iostream> and included the using namespace std; . This seems to have fixed all the errors I...
9
by: mikron30 | last post by:
In the following code I am getting the following warning warning C4213: nonstandard extension used : cast on l-value class X { public: operator bool() {}; }; class Y
26
by: HP | last post by:
Hi guys i wana remove this warning which i am getting during my codcomilation. the warning is - Possible use of null pointer 'PnoSytGenericTest::_response' in left argument to operator '->'
16
by: jose_luis_fdez_diaz_news | last post by:
Hi, If I don't include <libgen.h> I get then warnig below in regcmp call: warning: improper pointer/integer combination: op "=" but if I include it the warning is not shown, but them program...
3
by: Bas Wassink | last post by:
Hello there, I'm having trouble understanding a warning produced by 'splint', a code-checker. The warning produced is: keywords.c: (in function keyw_get_string) keywords.c:60:31: Released...
40
by: Dave Hansen | last post by:
Please note crosspost. Often when writing code requiring function pointers, it is necessary to write functions that ignore their formal parameters. For example, a state machine function might...
11
by: zeppe | last post by:
Hi all, I've a problem. The code that follows creates a warning in both gcc and visual c++. However, I think it's correct: basically, there is a function that return an object of a derived...
92
by: Heinrich Pumpernickel | last post by:
what does this warning mean ? #include <stdio.h> int main() { long l = 100; printf("l is %li\n", l * 10L);
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
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...

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.