www.digitalmars.com         C & C++   DMDScript  

c++ - Unneeded warning

reply Sanel <Sanel_member pathlink.com> writes:
Hello,
i'm getting strange warning when there is use temp object.
Here is snippet:

const char* foo(void)
{
const char* test = " test ";
return test;
}

int main()
{
const char* c;
if(!(c = foo()))
/* ... */
else
/* ... */
return 0;
}

I'm getting this:

if(!(c = foo()))
^
test.cpp(12) : Warning 2: possible unintended assignment
link test,,,user32+kernel32/noi;

Here should not be warning since temporary object is created. 

Comments ?
Sanel
Oct 05 2004
next sibling parent reply Heinz Saathoff <hsaat despammed.com> writes:
Hello,

Sanel wrote...
 I'm getting this:
 
 if(!(c = foo()))
 ^
 test.cpp(12) : Warning 2: possible unintended assignment

The compiler warns if an assignment is used where a comparison might have been intended. The warning message is not given when the if- expression is written as if((c = foo()) == false) because of the explicit comparison operator is seen. - Heinz
Oct 05 2004
parent reply Sanel <Sanel_member pathlink.com> writes:
Yes,
but there should be silent implicit comparison. For example, GCC with -Wall
option
does not say anything and i am thinking that warning for obvious expression 
should not be.

Am i wrong ?

Sanel

The compiler warns if an assignment is used where a comparison might 
have been intended. The warning message is not given when the if-
expression is written as
   if((c = foo()) == false) 
because of the explicit comparison operator is seen.


- Heinz
 

Oct 05 2004
next sibling parent reply Heinz Saathoff <hsaat despammed.com> writes:
Hello,

Sanel wrote...
 Yes,
 but there should be silent implicit comparison. For example, GCC with -Wall
 option
 does not say anything and i am thinking that warning for obvious expression 
 should not be.
 
 Am i wrong ?

No, because ! should tell the compiler that the result of (c=foo()) is implicitly converted to bool and implicitly compared for equality with false. In my opinion the extra parenthesis also could prevent the warning so that if( c=foo() ) ...; // gives warning if( (c=foo()) ) ....; // no warning On the other hand, as long as it's a warning it doen't matter. In the beginning when I switched from Pascal to C I often made this mistake (same with forgetting parenthesis when calling a function). - Heinz
Oct 06 2004
parent reply Sanel <Sanel_member pathlink.com> writes:
Hi,
am i missing something here. As you can see in my first post, i stated
"if(!(c = foo()))" 

false. In my opinion the extra parenthesis also could prevent the 
warning so that

so this is compiler specific issue. This has nothing to do with extra parenthesis.
On the other hand, as long as it's a warning it doen't matter

become annoying. What Walter say about this ? Sanel In article <MPG.1bcdf5eed178f13a9896eb news.digitalmars.com>, Heinz Saathoff says...
Hello,

Sanel wrote...
 Yes,
 but there should be silent implicit comparison. For example, GCC with -Wall
 option
 does not say anything and i am thinking that warning for obvious expression 
 should not be.
 
 Am i wrong ?

No, because ! should tell the compiler that the result of (c=foo()) is implicitly converted to bool and implicitly compared for equality with false. In my opinion the extra parenthesis also could prevent the warning so that if( c=foo() ) ...; // gives warning if( (c=foo()) ) ....; // no warning On the other hand, as long as it's a warning it doen't matter. In the beginning when I switched from Pascal to C I often made this mistake (same with forgetting parenthesis when calling a function). - Heinz

Oct 06 2004
next sibling parent reply Heinz Saathoff <hsaat despammed.com> writes:
Hello,

Sanel wrote...
 Hi,
 am i missing something here. As you can see in my first post, i stated
 "if(!(c = foo()))" 

I saw that! IMO the ! operator should be enough to suppress the warning. My extra note was that the warning could also be suppressed by the parenthesis around the assignment.
false. In my opinion the extra parenthesis also could prevent the 
warning so that

so this is compiler specific issue. This has nothing to do with extra parenthesis.

Right, it's the way the compiler issues warnings. Warnings are not necessary errors, that's why files with only warnings still compile. It's only a hint to the programmer that he might have intended something different. If you ever have used lint you know that you get lot's more of warnings.
On the other hand, as long as it's a warning it doen't matter

become annoying.

Compilers can behave different here as long as they compile otherwise valid code (and your example is valid). If you want to have a warning clean built you can either suppress this warning with the command line switch -w2 or change the code a bit.
 What Walter say about this ?

- Heinz
Oct 06 2004
parent reply Sanel <Sanel_member pathlink.com> writes:
I saw that! IMO the ! operator should be enough to suppress the warning. 
My extra note was that the warning could also be suppressed by the 
parenthesis around the assignment.

Try it. ;)
Right, it's the way the compiler issues warnings. Warnings are not 
necessary errors, that's why files with only warnings still compile. 
It's only a hint to the programmer that he might have intended something 
different.

That is ok, but if we get warning for every little bit odd expression where we will go. To stop this confusion, here is the statement from standard: "The value of a condition that is an initialized declaration in a statement other than a switch statement is the value of the declared variable implicitly converted to type bool." and "The value of a condition that is an expression is the value of the expression, implicitly converted to bool, for statements other than switch..."
switch -w2 or change the code a bit.

Don't know. I appreciate warnings.

Good warnings are bless. Sanel
- Heinz

Oct 06 2004
parent Heinz Saathoff <hsaat despammed.com> writes:
Hello,

Sanel wrote...
I saw that! IMO the ! operator should be enough to suppress the warning. 
My extra note was that the warning could also be suppressed by the 
parenthesis around the assignment.

Try it. ;)

Yes, DM issues a warning. In my opinion the warning could be suppressed in this case because with the parenthesis the programmer tells the compiler that he knows what he is doing.
 To stop this confusion, here is the statement from standard:
 
 "The value of a condition that is an initialized declaration in a statement
 other than a switch statement is the value of the declared variable implicitly
 converted to type bool."
 
 and
 
 "The value of a condition that is an expression is the value
 of the expression, implicitly converted to bool, for statements other than
 switch..."

That's all right and DMC doesn't reject the valid code. It only gives a warning. The standard doesn't tell anything about warnings, only about errors that must be detected by the compiler.
switch -w2 or change the code a bit.

Don't know. I appreciate warnings.

Good warnings are bless.

Ack! - Heinz
Oct 06 2004
prev sibling parent "Walter" <newshound digitalmars.com> writes:
"Sanel" <Sanel_member pathlink.com> wrote in message
news:ck0r7b$2cjq$1 digitaldaemon.com...
 You are right, but when you try to port code written for other compilers,

 become annoying.

 What Walter say about this ?

There is no consensus among C++ compiler vendors on what things should be warnings and what things shouldn't be. In fact, sometimes warnings are contradictory - adjusting the code to not warn with one compiler will cause a warning with another. This is why warnings can usually be individually turned on or off with compiler switches.
Oct 06 2004
prev sibling parent Daniel James <daniel calamity.org.uk> writes:
Sanel wrote:
 Yes,
 but there should be silent implicit comparison. For example, GCC with -Wall
 option
 does not say anything and i am thinking that warning for obvious expression 
 should not be.

IMHO gcc gets this wrong. It doesn't warn about the following if statement: if(!(a = b && c == d)) which is probably a mistake. To be able to do what you want, and get something like this right, is not easy. Interestingly g++-3.4 seems to have dropped the warning completely - although, I don't think I've got the latest version, so it might have changed. Personally, I try to avoid using the return value of an assignment, so I appreciate the warning. Daniel
Oct 06 2004
prev sibling parent reply Arjan Knepper <arjan ask.me> writes:
Sanel wrote:

 Hello,
 i'm getting strange warning when there is use temp object.
 Here is snippet:
 
 const char* foo(void)
 {
 const char* test = " test ";
 return test;
 }
 
 int main()
 {
 const char* c;
 if(!(c = foo()))
 /* ... */
 else
 /* ... */
 return 0;
 }
 
 I'm getting this:
 
 if(!(c = foo()))
 ^
 test.cpp(12) : Warning 2: possible unintended assignment
 link test,,,user32+kernel32/noi;
 
 Here should not be warning since temporary object is created. 
 
 Comments ?
 Sanel

The warning is about the assigment of 'c' in the if ( !( c = foo() ) ). To get rid of it: c = foo (); if ( ! c ) Btw be aware of the scope of the temp obj pointed by and returned in 'test' by the function foo (). The object does not exist anymore when de function 'foo ()' returns, so where is 'test' pointing at?? Arjan
Oct 05 2004
parent reply Sanel <Sanel_member pathlink.com> writes:
Btw be aware of the scope of the temp obj pointed by and returned in 
'test' by the function foo (). The object does not exist anymore when de 
  function 'foo ()' returns, so where is 'test' pointing at??

This is not true. Test points on static part of program memory, so until someone does test = "something else" or test = 0 it will remain the same. Note that 'test' is declared as const char *test=... not as const char test[]=... Sanel
Oct 05 2004
parent reply Sanel <Sanel_member pathlink.com> writes:
Ups, here was typo.
Instead 'test' should be 'c' var if that is outside foo() function. But you
know what i mean. 'c' will point on the same address as 'test' in foo().

:) 

In article <cju7o0$1jj$1 digitaldaemon.com>, Sanel says...
Btw be aware of the scope of the temp obj pointed by and returned in 
'test' by the function foo (). The object does not exist anymore when de 
  function 'foo ()' returns, so where is 'test' pointing at??

This is not true. Test points on static part of program memory, so until someone does test = "something else" or test = 0 it will remain the same. Note that 'test' is declared as const char *test=... not as const char test[]=... Sanel

Oct 05 2004
parent Arjan Knepper <arjan ask.me> writes:
Sanel wrote:
 Ups, here was typo.
 Instead 'test' should be 'c' var if that is outside foo() function. But you
 know what i mean. 'c' will point on the same address as 'test' in foo().
 
 :) 

Yes I understood. And you are right. I had the impression you were creating a local scoped object in foo () and returning a pointer to it. Because you talked about a "temporary object is created". I should have red more carefully. Arjan
 
 In article <cju7o0$1jj$1 digitaldaemon.com>, Sanel says...
 
Btw be aware of the scope of the temp obj pointed by and returned in 
'test' by the function foo (). The object does not exist anymore when de 
 function 'foo ()' returns, so where is 'test' pointing at??

This is not true. Test points on static part of program memory, so until someone does test = "something else" or test = 0 it will remain the same. Note that 'test' is declared as const char *test=... not as const char test[]=... Sanel


Oct 05 2004