Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is thi me or GCC

0 views
Skip to first unread message

Nick

unread,
Nov 7, 2009, 12:11:05 PM11/7/09
to
I've just started to get a strange warning from GCC. Can you check my
code for me and check that this is GCC being silly - and so it should be
reported as a bug - not me missing something.

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

Flash Gordon

unread,
Nov 7, 2009, 12:49:18 PM11/7/09
to
Nick wrote:
> I've just started to get a strange warning from GCC. Can you check my
> code for me and check that this is GCC being silly - and so it should be
> reported as a bug - not me missing something.
>
> 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.

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

Seebs

unread,
Nov 7, 2009, 1:20:29 PM11/7/09
to
On 2009-11-07, Nick <3-no...@temporary-address.org.uk> wrote:
> for(s=a; s && *s; s && ++s) {

> 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!

Seebs

unread,
Nov 7, 2009, 2:09:19 PM11/7/09
to
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.

James Dow Allen

unread,
Nov 7, 2009, 3:29:18 PM11/7/09
to
On Nov 8, 1:20 am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2009-11-07, Nick <3-nos...@temporary-address.org.uk> wrote:
[snipped]
> > (s && ++s)
> >
> > .... GCC complains "value computed is not used".

> > That's true of course, but the same is true of the
> > traditional "++s".

> 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

Flash Gordon

unread,
Nov 7, 2009, 3:17:11 PM11/7/09
to
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'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

lawrenc...@siemens.com

unread,
Nov 7, 2009, 5:30:54 PM11/7/09
to
James Dow Allen <jdall...@yahoo.com> wrote:
>
> 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!

It is. Most emphatically.
--
Larry Jones

Honey, are we out of aspirin again? -- Calvin's Dad

Alan Curry

unread,
Nov 7, 2009, 6:37:26 PM11/7/09
to
In article <slrnhfbenp.t1r...@guild.seebs.net>,

Seebs <usenet...@seebs.net> wrote:
>On 2009-11-07, Nick <3-no...@temporary-address.org.uk> wrote:
>> for(s=a; s && *s; s && ++s) {
>
>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.

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

Barry Schwarz

unread,
Nov 7, 2009, 8:04:09 PM11/7/09
to
On Sat, 07 Nov 2009 20:17:11 +0000, Flash Gordon
<sm...@spam.causeway.com> wrote:

>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

Keith Thompson

unread,
Nov 8, 2009, 1:36:03 AM11/8/09
to
lawrenc...@siemens.com writes:
> James Dow Allen <jdall...@yahoo.com> wrote:
>> 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!
>
> It is. Most emphatically.

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"

Malcolm McLean

unread,
Nov 8, 2009, 9:28:01 AM11/8/09
to

"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. If s is NULL ++s is non-null, if s is
0xFFFF ++s is undefined.
So the expression is unused.


Ben Bacarisse

unread,
Nov 8, 2009, 10:27:20 AM11/8/09
to
"Malcolm McLean" <regn...@btinternet.com> writes:

> "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.

Malcolm McLean

unread,
Nov 8, 2009, 10:44:23 AM11/8/09
to

"Ben Bacarisse" <ben.u...@bsb.me.uk> wrote in message

> 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.
>
Almost certainly ++ 0xBEEF will evaluate to 0xBEF0 and give a value of true.
0xFFFF however will probably roll over to 0x0000 and may give a value of
false. However in this case the compiler is clever enough to pick up that
this is undefined. Hence ++s can never evaluate to null in a valid program.

++ 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").


Phil Carmody

unread,
Nov 8, 2009, 11:03:08 AM11/8/09
to
"Malcolm McLean" <regn...@btinternet.com> writes:
> "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. If s is NULL ++s is non-null, if s is
> 0xFFFF ++s is undefined.

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

Seebs

unread,
Nov 8, 2009, 12:25:51 PM11/8/09
to
On 2009-11-08, Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
> Rather, ++s can never be both well-defined and false.

For a pointer, true. :)

(unsigned long s = -1; if (++s)...)

Malcolm McLean

unread,
Nov 8, 2009, 3:23:30 PM11/8/09
to

"Phil Carmody" <thefatphi...@yahoo.co.uk> wrote in message

> 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.
>
Then you'd need more that 64000 bytes of memory installed. That's a lot of
values. What sort of equations do you calculate?

Robert Latest

unread,
Nov 8, 2009, 4:05:07 PM11/8/09
to
Nick wrote:
> for(s=a; s && *s; s && ++s) {

what's the purpose of the 's && ++s' thingy?
Why not just write '++s'?

robert

Seebs

unread,
Nov 8, 2009, 4:21:57 PM11/8/09
to

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.

Richard

unread,
Nov 8, 2009, 4:31:09 PM11/8/09
to
Robert Latest <bobl...@yahoo.com> writes:

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

Richard Heathfield

unread,
Nov 8, 2009, 4:53:21 PM11/8/09
to

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

Flash Gordon

unread,
Nov 8, 2009, 4:59:56 PM11/8/09
to


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

Nick

unread,
Nov 9, 2009, 2:48:50 AM11/9/09
to
Robert Latest <bobl...@yahoo.com> writes:

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.

Phil Carmody

unread,
Nov 9, 2009, 2:57:26 AM11/9/09
to

Are you regressing into childhood, or something?
65535 became insignificant decades ago.

Joe Wright

unread,
Nov 9, 2009, 6:39:17 AM11/9/09
to
Phil Carmody wrote:
> "Malcolm McLean" <regn...@btinternet.com> writes:
>> "Phil Carmody" <thefatphi...@yahoo.co.uk> wrote in message
>>> 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.
>> Then you'd need more that 64000 bytes of memory installed. That's a lot of
>> values. What sort of equations do you calculate?
>
> Are you regressing into childhood, or something?
> 65535 became insignificant decades ago.
>
> Phil

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."

Robert Latest

unread,
Nov 9, 2009, 3:37:34 PM11/9/09
to
Richard wrote:
> Robert Latest <bobl...@yahoo.com> writes:
>
>> Nick wrote:
>>> for(s=a; s && *s; s && ++s) {
>>
>> what's the purpose of the 's && ++s' thingy?
>> Why not just write '++s'?
>>
>> robert
>
> Because otherwise it would crash ... Read the code.

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

Dik T. Winter

unread,
Nov 11, 2009, 8:53:49 AM11/11/09
to
In article <87639mb...@temporary-address.org.uk> Nick <3-no...@temporary-address.org.uk> writes:
...

> for(s=a; s && *s; s && ++s) {
...

> 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".

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/

0 new messages