Here's a cut-down example:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *s;
char *a = "this is + some stuff";
for(s=a; s && *s; s && ++s) {
printf("[%c]",*s);
if(*s == '+')
s = NULL;
}
printf("\n");
return 0;
}
OK, not very elegant, but setting the pointer to null part way through
to abort the loop should work (I know I could use "break" - the real
example is more complicated).
It's that "s && ++s" in the third stanza of the for() that's causing the
problems. GCC complains "value computed is not used". That's true of
course, but the same is true of the traditional "++s". I can get round
it by casting that expression to void but surely I shouldn't need to do
this.
I see a few bug reports floating round of GCC being over-zealous with
this report in the latest version. So is my code fine, in which case
I'll complain about GCC, or should any decent compiler be complaining
about it (and in which case, for my education, why?)?
--
Online waterways route planner: http://canalplan.org.uk
development version: http://canalplan.eu
Well, you *are* computing a value that you are not using!
> I see a few bug reports floating round of GCC being over-zealous with
> this report in the latest version. So is my code fine, in which case
> I'll complain about GCC, or should any decent compiler be complaining
> about it (and in which case, for my education, why?)?
It's a judgment call which is why the warning is not compulsory! You are
"calculating" a value which you are not using. It just happens that you
are not concerned with the value calculated.
--
Flash Gordon
> It's that "s && ++s" in the third stanza of the for() that's causing the
> problems. GCC complains "value computed is not used". That's true of
> course, but the same is true of the traditional "++s". I can get round
> it by casting that expression to void but surely I shouldn't need to do
> this.
That is... odd.
> I see a few bug reports floating round of GCC being over-zealous with
> this report in the latest version. So is my code fine, in which case
> I'll complain about GCC, or should any decent compiler be complaining
> about it (and in which case, for my education, why?)?
Sure looks buggy to me. Hmm.
Just thinking about it, I suspect that this is being caused by the &&,
but it does seem like a bug in gcc.
-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
Well, yes.
> It's a judgment call which is why the warning is not compulsory! You are
> "calculating" a value which you are not using. It just happens that you
> are not concerned with the value calculated.
The thing is, a normal for loop does that too:
for (i = 0; i < 10; ++i)
So why does gcc warn about this? My guess is that they've special-cased
this partially, but when you write "s && s++", the compiler is confused;
it could understand disregarding the new value of s, and in any event
that value is used shortly later. But when you write "s && s++", you
compute another value -- 0 or 1 -- which is completely unused and not part
of the loop control.
It might be interesting to see whether such versions of gcc complain about:
int x = 0, i;
for (i = 0; x < 10; ++i) {
x++;
}
because the computed value of i is never used.
> That is... odd.
Well, ++s assigns to an lvalue.
(s && ++s) does that, *while creating*
a higher-level rvalue which gets discarded. But I
think gcc's decision of when to issue this "not used"
warning is probably based on an arbitrary heuristic
that isn't expected to be fool-proof.
For example, I think gcc complains on
(s && (s += 1))
but not
(s && (s = 1))
OP could change to the non-warning
(s += !!s)
But, although adding 0 is normally a do-nothing,
I'd check with the lawyers in case adding 0 to a
null pointer is somehow prohibited!
James
I've never seen it warn in that case, and I think it is probable that
++/-- are special cased because it is so often used for the side effect
rather than for the return value.
--
Flash Gordon
It is. Most emphatically.
--
Larry Jones
Honey, are we out of aspirin again? -- Calvin's Dad
Maybe it just thinks the result of a && expression shouldn't normally be
ignored. If you disagree, that's not a sign of a bug.
The lack of a warning for this version:
for(s=a; s && *s; s ? ++s : 0)
could be called a bug in the opposite direction, if you think that the
ternary operator's result also shouldn't be ignored.
--
Alan Curry
>Seebs wrote:
>> On 2009-11-07, Flash Gordon <sm...@spam.causeway.com> wrote:
>>> Well, you *are* computing a value that you are not using!
>>
>> Well, yes.
>>
>>> It's a judgment call which is why the warning is not compulsory! You are
>>> "calculating" a value which you are not using. It just happens that you
>>> are not concerned with the value calculated.
>>
>> The thing is, a normal for loop does that too:
>> for (i = 0; i < 10; ++i)
>>
>> So why does gcc warn about this? My guess is that they've special-cased
>> this partially, but when you write "s && s++", the compiler is confused;
>> it could understand disregarding the new value of s, and in any event
>> that value is used shortly later. But when you write "s && s++", you
>> compute another value -- 0 or 1 -- which is completely unused and not part
>> of the loop control.
>>
>> It might be interesting to see whether such versions of gcc complain about:
>>
>> int x = 0, i;
>> for (i = 0; x < 10; ++i) {
>> x++;
>> }
>>
>> because the computed value of i is never used.
>
I wonder if the warning in the original posting was not about the ++
expression but about the && expression. The result of the original
expression is 0 or 1 (and a possible side effect) which is not used
anywhere.
Someone with gcc could test the two equivalent statements
++i;
and
1 && ++i;
or the almost equivalent but closer to the original code
i && ++i;
to determine what is driving gcc to produce the diagnostic in
question.
--
Remove del for email
Where "prohibited" means the behavior is undefined. Adding 0 to
a null pointer is likely to yield a null pointer on many, perhaps
most, implementations -- which just means that many, perhaps
most, implementations won't catch this bug for you.
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
> "Nick" <3-no...@temporary-address.org.uk> wrote in message
>> char *s;
>> for(s=a; s && *s; s && ++s)
> ++s can never evaluate to false.
Rather, ++s can never be both well-defined and false. Since undefined
behaviour can be anything, when ++s is undefined its value can appear
to be false in every way that might matter to a program.
> If s is NULL ++s is non-null, if s is 0xFFFF ++s is undefined.
If s is null, ++s is undefined. In that sense it might appear to be
non-null. As to the second half of your remark, it seems odd to pick
out one value. ++s is probably undefined for a very large set of
values for s.
> So the expression is unused.
But that is not the kind of "not used" that gcc is complaining about.
For example, you get the same message if the last clause in the "for"
statement is, say, i && ++j where everything is well-defined.
--
Ben.
++ null may well be defined and possibly even useful. ("Undefined behaviour"
means "undefined by the C standard", not "lives in some Platonic abstaction
of indefinitness").
If s is NULL, ++s isn't even evaluated! If s is (char*)0xFFFF, then
++s may well be (char*)0x10000, and not undefined at all.
> So the expression is unused.
It's clearly used for its side effects. The _value_ of the expression
may be unused, but that's true for many expresions, including most simple
assignments.
Phil
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
For a pointer, true. :)
(unsigned long s = -1; if (++s)...)
what's the purpose of the 's && ++s' thingy?
Why not just write '++s'?
robert
Because s might be set to null in the loop.
At which point:
1. It's undefined behavior to "++s".
2. If it did the most obvious thing, it would result in the loop control
ending up with a non-null pointer.
Because otherwise it would crash ... Read the code.
--
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c
Consider the possibility that a is a null pointer.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
What are you talking about? All it needs in one byte of memory at
location 0xFFFF and more than 16 bits of address space. That covers
every PC I've used for the last 20+ years, and from memory of the OPs
post it looked more likely that it was a hosted system than an embedded one.
--
Flash Gordon
Have a look at the rest of the code - I set s to NULL under a particular
set of circumstances in order to terminate the loop early.
In real life, in that example, you'd just use a break, but consider -
for example - that there could be a switch on *s inside the loop and you want
to exit when it's a particular value. You can't use break in those
circumstances. You could use an auxiliary 'done' variable, of course.
But doing it this way is entirely legal, and not - I submit - something
a compiler ought (as distinct from "can"!) complain about.
Are you regressing into childhood, or something?
65535 became insignificant decades ago.
PC's now have ten times that much, more than anybody will ever need. :-)
--
Joe Wright
"If you rob Peter to pay Paul you can depend on the support of Paul."
Ah, I see. Because the third thingy in the for loop is done before
the test. Nice. Altough I avoid manipulating the loop variable -- either
by using break, or by having an additional flag variable that gets
tested in the for() line.
robert
Not really. In "++s" the computed value is assigned to s. In the original
the result of the logical and is not used.
--
dik t. winter, cwi, science park 123, 1098 xg amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/