Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ SMAUG
➜ SMAUG coding
➜ New Linux, New GCC, New Warnings
New Linux, New GCC, New Warnings
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Pages: 1 2
3
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Mon 14 Jan 2008 09:55 AM (UTC) |
Message
| I have just upgraded to SuSe 10.3 which has gcc 4.2.1 installed and now i get a whole bunch of warnings when i compile my smaug code.
act_wiz.c:4578: warning: the address of ‘arg’ will always evaluate as ‘true’
if( arg && arg[0] != '\0' )
All the warnings are the same and on that type of expression. I know these are nothing to worry about, but is there any way that i can re-write those lines to not trip the warning. I like not having any warnings when i compile.
Thanks for helping.
|
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #1 on Mon 14 Jan 2008 05:31 PM (UTC) |
Message
|
Quote:act_wiz.c:4578: warning: the address of ‘arg’ will always evaluate as ‘true’
Chances are that 'arg' is a local variable allocated on the stack, e.g.
char arg[1234];
So, it cannot be null and therefore will always have an address causing it to always be 'true'. To remove the warning, it suffices to remove the redundant check:
|
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #2 on Tue 15 Jan 2008 05:21 AM (UTC) |
Message
| Is there any particular reason why the original coders wrote it in such a manner, differences in how gcc2 and gcc4 operate perhaps? |
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #3 on Tue 15 Jan 2008 05:33 AM (UTC) |
Message
| It could be many things. I see three likely scenarios:
1. It used to be checking an argument that actually could be null, such as the 'argument' parameter. But then it got changed to 'arg', and nobody bothered changing the condition.
2. Somebody typed it out of habit, because you almost always check strings for null before dereferencing them.
3. Somebody typed it because they copy/pasted and didn't know any better.
I think option 1 is most likely though. It's also probable that earlier versions of gcc didn't notice it and so didn't give a warning. (But a local array like that always has a non-null address, no matter what version of gcc you're using.) |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #4 on Tue 15 Jan 2008 07:00 AM (UTC) |
Message
| Got another question for you David LOL,
bank.c:250: warning: the address of ‘arg1’ will never be NULL
if ( arg1 == '\0' )
{
snprintf( buf, MAX_STRING_LENGTH, "%s How much gold do you wish to withdraw?", ch->name );
do_tell( banker, buf );
return;
}
Changing \0 to NULL removes the warning, whats the difference between NULL and \0.
Is it that NULL is a value meaning 0 and \0 is a memory location, |
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #5 on Tue 15 Jan 2008 07:07 AM (UTC) |
Message
| Well first off this is the same warning, basically; arg1 being a local buffer will never have a zero value.
As for why '\0' causes a warning but NULL doesn't, err, I don't know. :) Some systems define NULL as a special keyword for the compiler; others define it as 0; others yet define it as ((void*)0) (this last one is the most common for C I think; I read somewhere that C++ defines it as 0). Maybe the compiler can detect a comparison to zero directly, but isn't smart enough to detect comparison to the other things?
What if you try just arg1 == 0, and then arg1 == ((void*)0)? Maybe we can figure out which one it's not smart enough to figure out for the warning. :-) |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #6 on Tue 15 Jan 2008 07:22 AM (UTC) |
Message
|
if ( arg1 == ((void*)0) )
This one it likes, but == 0 gives the warning.
Also, these 2 are both liked by the compiler.
if ( arg1[0] == 0 )
if ( arg1[0] == '\0')
|
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #7 on Tue 15 Jan 2008 07:28 AM (UTC) |
Message
| Also,
if( !arg1 || !arg2 ) this gives the warning, and im going to assume that this is a fair replacement for this line,
if( arg1[0] != '\0' || arg2[0] != '\0' )
On another note, i just found i have a NULLSTR macro used locally in the liquids code, think i might have to fix it up to not give the error, make it global and use it wherever those checks are made.
|
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #8 on Tue 15 Jan 2008 07:34 AM (UTC) |
Message
|
Quote:if ( arg1 == ((void*)0) )
This one it likes, but == 0 gives the warning.
That's kind of funny -- it's smart enough to realize that == 0 is comparing to zero, but == ((void*)0) isn't. :-) Ah, well...
Quote: Also, these 2 are both liked by the compiler.
if ( arg1[0] == 0 )
if ( arg1[0] == '\0')
Yeah, that's ok though, since arg1[0] is of type char and could be zero. 0 and '\0' are the same thing (== 0).
Quote:
if( !arg1 || !arg2 ) this gives the warning, and im going to assume that this is a fair replacement for this line,
if( arg1[0] != '\0' || arg2[0] != '\0' )
Yes that looks like a reasonable replacement, except for one thing: the original code says:
if arg1 is null (i.e. empty) or arg2 is null (i.e. empty)
The new code says:
if arg1 is NOT empty or arg2 is NOT empty
So if you change the != to == you'll be preserving the intent of the original code. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #9 on Tue 15 Jan 2008 07:34 AM (UTC) |
Message
| This line,
sprintf( buf, corpse_descs[UMIN( timerfrac - 1, 4 )], bufptr );
Gives this warning,
update.c:1496: warning: format not a string literal, argument types not checked
And this is how i fixed it,
sprintf( buf, "%s %s",corpse_descs[UMIN( timerfrac - 1, 4 )], bufptr );
There are a few other places where this happens, is there any real need to have the %s, does it serve any real purpose if only to check that your putting the right things into the variables. |
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #10 on Tue 15 Jan 2008 07:36 AM (UTC) |
Message
| Heh, you replied just a few seconds after I did. :-)
What you did doesn't quite do the same thing. The original code uses the variable string as the actual format string, and passes in the argument as a parameter to the format string. In the new version, you're just concatenating the two.
The warning is ok, though, as long as you're always sure that the passed in argument corresponds to whatever the format string is expecting. For instance if the format string has a %s in it and you pass in a number, you'll be in for trouble... |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #11 on Tue 15 Jan 2008 07:48 AM (UTC) |
Message
| Ok i think i get what your saying. In that example
corpse_descs[UMIN( timerfrac - 1, 4 )] = abcd
bufptr = efgh
buf then = abcdefgh
where as if i had the %s %s buf would then = abcd efgh, which could screw up the formatting of some strings through out the game if i was to change those warnings to use the %s.
|
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #12 on Tue 15 Jan 2008 07:51 AM (UTC) |
Message
| Actually here's a better example...
char * fmtstr = "%s";
bufptr = "abc";
sprintf( buf, fmtstr, bufptr );
Now, buf will contain "abc".
But here:
char * fmtstr = "%s";
bufptr = "abc";
sprintf( buf, "%s %s" fmtstr, bufptr );
buf contains "%s abc". The reason is that the first %s takes the value of fmtstr (which is just "%s") and the second %s takes the value of bufptr (which is "abc").
In other words by pushing the format string into the printf parameters, you make it a string just like any other. But, if you use a variable as the format string, the compiler can no longer verify at compile time that the arguments you're using make sense, which is why it's giving you a warning. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #13 on Tue 15 Jan 2008 08:08 AM (UTC) Amended on Tue 15 Jan 2008 08:09 AM (UTC) by Robert Powell
|
Message
| Arhhh now it makes sence. Im starting to enjoy this lesson, now onto the tough ones, const char * casts and all those scary things.
board.c:908: warning: cast discards qualifiers from pointer target type
void make_note( const char *board_name, const char *sender, const char *to, const char *subject, const int expire_days,
const char *text )
line 908>> note->sender = STRALLOC( ( char * )sender );
const char, char * and casts are not something i know much(anything) about, but i would like to know more, i think about the only thing i think i know is that you use a const when whats being stored is not expected to change.
Heh, this might be a good topic for one of Nicks Legendary Tutorials. |
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| Nick Gammon
Australia (23,140 posts) Bio
Forum Administrator |
Date
| Reply #14 on Tue 15 Jan 2008 08:23 AM (UTC) |
Message
|
Quote:
Got another question for you David LOL,
bank.c:250: warning: the address of ‘arg1’ will never be NULL
if ( arg1 == '\0' )
{
snprintf( buf, MAX_STRING_LENGTH, "%s How much gold do you wish to withdraw?", ch->name );
do_tell( banker, buf );
return;
}
Changing \0 to NULL removes the warning, whats the difference between NULL and \0.
You don't mean that backwards do you? Why would it complain arg1 is never NULL, if you are comparing to \0?
NULL and \0 are really quite different things.
- NULL is technically a "pointer to nothing" which is often implemented as a pointer containing the address zero.
See: http://c-faq.com/null/varieties.html
and: http://c-faq.com/null/macro.html
- The representation \0 refers to the value zero. As the FAQ above says you should only use NULL for pointers and not values. As an example:
char * p;
p = malloc (10);
if (p != NULL)
*p = '\0';
Internally NULL and \0 may well both refer to zero however one is a pointer and one is the value the pointer is pointing to.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
75,629 views.
This is page 1, subject is 3 pages long: 1 2
3
It is now over 60 days since the last post. This thread is closed.
Refresh page
top