A C question (about strlen)

A C question (about strlen)

Post by Kenny McCorma » Wed, 31 Jul 2002 11:25:45



(I know this is somewhat O/T in cup, but I prefer not to post to clc, ever)

Anyway, this caught me recently:

#include <stdio.h>
#include <string.h>

int main()
{
        int x = -10;

        if (x > strlen("abc")) puts("Weird!");
        exit(0);

Quote:}

Looking in the include files shows that strlen now returns unsigned, and
this causes the comparison to be done as unsigned.  The fix is:

        if (x > (int) strlen("abc")) puts("Weird!");

but I am curious as to whether there is a good way to avoid making this
mistake in the first place.  It sure wasn't obvious to me why one should
get bit for this.

 
 
 

A C question (about strlen)

Post by Marc Rochkin » Wed, 31 Jul 2002 11:51:40


Looks like gcc let's this go. Other compilers I've used give a warning on
comparing signed and unsigned integers. Perhaps there is a gcc option to
increase the warning level.


Quote:> (I know this is somewhat O/T in cup, but I prefer not to post to clc,
ever)

> Anyway, this caught me recently:

> #include <stdio.h>
> #include <string.h>

> int main()
> {
>         int x = -10;

>         if (x > strlen("abc")) puts("Weird!");
>         exit(0);
> }

> Looking in the include files shows that strlen now returns unsigned, and
> this causes the comparison to be done as unsigned.  The fix is:

>         if (x > (int) strlen("abc")) puts("Weird!");

> but I am curious as to whether there is a good way to avoid making this
> mistake in the first place.  It sure wasn't obvious to me why one should
> get bit for this.


 
 
 

A C question (about strlen)

Post by Rich Tee » Wed, 31 Jul 2002 11:54:10



> (I know this is somewhat O/T in cup, but I prefer not to post to clc, ever)

DOn't blaem you...

Quote:>         int x = -10;

>         if (x > strlen("abc")) puts("Weird!");
>         exit(0);
> }

> Looking in the include files shows that strlen now returns unsigned, and
> this causes the comparison to be done as unsigned.  The fix is:

>         if (x > (int) strlen("abc")) puts("Weird!");

> but I am curious as to whether there is a good way to avoid making this
> mistake in the first place.  It sure wasn't obvious to me why one should
> get bit for this.

Why are you setting x to -10?  This strikes me as one of
those DDT (Don't Do That) situations.

--
Rich Teer

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-online.net

 
 
 

A C question (about strlen)

Post by Erik Max Franci » Wed, 31 Jul 2002 12:54:22



> Looking in the include files shows that strlen now returns unsigned,
> and
> this causes the comparison to be done as unsigned.  The fix is:

>         if (x > (int) strlen("abc")) puts("Weird!");

> but I am curious as to whether there is a good way to avoid making
> this
> mistake in the first place.  It sure wasn't obvious to me why one
> should
> get bit for this.

Turn up the warning levels in your compiler:


strlen.c: In function `main':
strlen.c:9: warning: comparison between signed and unsigned

--

 __ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/  \ See the son in your bad day / Smell the flowers in the valley
\__/ Chante Moore
    Bosskey.net: Aliens vs. Predator 2 / http://www.bosskey.net/avp2/
 A personal guide to Aliens vs. Predator 2.

 
 
 

A C question (about strlen)

Post by Floyd Davidso » Wed, 31 Jul 2002 13:37:32



>Looks like gcc let's this go. Other compilers I've used give a warning on
>comparing signed and unsigned integers. Perhaps there is a gcc option to
>increase the warning level.

Invoking gcc with the -W option will generate a warning for
comparisons between signed and unsigned types.

Generally, using both -Wall and -W options to gcc will provide
about the lowest level of warnings from gcc that is reasonable.
When possible, I also enable these options,

   -Wcast-align
   -Wcast-qual
   -Wmissing-prototypes
   -Wshadow
   -Wnested-externs
   -Wstrict-prototypes
   -Waggregate-return
   -Wtraditional
   -Wpointer-arith

Of course -ansi and -pedantic are also useful.

--
Floyd L. Davidson         <http://www.ptialaska.net/~floyd>

 
 
 

A C question (about strlen)

Post by Dave Near » Wed, 31 Jul 2002 16:43:44


On Tue, 30 Jul 2002 02:25:45 GMT, Kenny McCormack said:

Quote:> (I know this is somewhat O/T in cup, but I prefer not to post to clc, ever)

It's not that scary :)

Quote:>         int x = -10
>         if (x > strlen("abc")) puts("Weird!");
> Looking in the include files shows that strlen now returns unsigned, and
> this causes the comparison to be done as unsigned.

strlen returns size_t, which is always unsigned. At least, C99
defines it as unsigned.

Quote:> but I am curious as to whether there is a good way to avoid making this
> mistake in the first place.  It sure wasn't obvious to me why one should
> get bit for this.

Ummm... other than using unsigned variables to check the value
returned by strlen, I can't think of one. Seems reasonable to me
that things like the size of an object and the length of a string
can be unsigned, though - so I'm not sure why this surprised you.

Cheers,
Dave.

--
           David Neary,
     E-Mail: bolsh at gimp dot org
CV: http://www.redbrick.dcu.ie/~bolsh/CV/CV.html

 
 
 

A C question (about strlen)

Post by Barry Margoli » Thu, 01 Aug 2002 04:21:53




Quote:>Ummm... other than using unsigned variables to check the value
>returned by strlen, I can't think of one. Seems reasonable to me
>that things like the size of an object and the length of a string
>can be unsigned, though - so I'm not sure why this surprised you.

There have been similar discussions about the types that off_t and size_t
expand into.  One point of view is that they should be unsigned (as size_t
is) because it doesn't make sense for an object to have negative size, and
this allows for larger objects.  The other point of view is that they
should be signed, so that you can use that type for variables that contain
the difference between two of them, which could be negative, e.g.

size_t size_diff;

size_diff = strlen(string1) - strlen(string2);

rather than:

long size_diff;

size_diff = (long)strlen(string1) - (long)strlen(string2);

If size_t is unsigned long, this won't even be valid for strings longer
than LONG_MAX.

--

Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

 
 
 

A C question (about strlen)

Post by Rich Tee » Thu, 01 Aug 2002 06:34:29



> There have been similar discussions about the types that off_t and size_t
> expand into.  One point of view is that they should be unsigned (as size_t
> is) because it doesn't make sense for an object to have negative size, and
> this allows for larger objects.  The other point of view is that they
> should be signed, so that you can use that type for variables that contain
> the difference between two of them, which could be negative, e.g.

> size_t size_diff;

> size_diff = strlen(string1) - strlen(string2);

> rather than:

> long size_diff;

Not to undermine what you've written, but in this specific example,
one would use ssize_t, which is signed.  What you wrote is perfectly
valid for types like off_t, of course.

--
Rich Teer

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-online.net

 
 
 

A C question (about strlen)

Post by Erik Max Franci » Thu, 01 Aug 2002 06:46:48



> There have been similar discussions about the types that off_t and
> size_t
> expand into.  One point of view is that they should be unsigned (as
> size_t
> is) because it doesn't make sense for an object to have negative size,
> and
> this allows for larger objects.

The point is, though, that size_t _is_ defined as an unsigned integral
type according to the relevant Standards.

--

 __ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/  \ See the son in your bad day / Smell the flowers in the valley
\__/ Chante Moore
    Bosskey.net: Aliens vs. Predator 2 / http://www.bosskey.net/avp2/
 A personal guide to Aliens vs. Predator 2.

 
 
 

A C question (about strlen)

Post by Kenny McCorma » Thu, 01 Aug 2002 06:48:15




Quote:>On Tue, 30 Jul 2002 02:25:45 GMT, Kenny McCormack said:

>strlen returns size_t, which is always unsigned. At least, C99
>defines it as unsigned.

OK - it still seems odd to me, but I can accept it.

Quote:>> but I am curious as to whether there is a good way to avoid making this
>> mistake in the first place.  It sure wasn't obvious to me why one should
>> get bit for this.

>Ummm... other than using unsigned variables to check the value
>returned by strlen, I can't think of one. Seems reasonable to me
>that things like the size of an object and the length of a string
>can be unsigned, though - so I'm not sure why this surprised you.

I've been programming in C for a long time, since before there were
prototypes and warnings and so on, in the days when it really was just one
step up from assembler in terms of (the lack of) error checking and the
general feeling of "caveat emptor".

In those days, I would not have been surprised at all (*), but nowadays,
with all the warnings and prototypes and what-not, I'm kinda surprised that
this could happen.  I.e., I think the new style of C coding gives one a
false sense of security...

It turns out, BTW, that, as others have posted, including "-W" on the gcc
command line will catch this.  I guess I was further surprised, again, as
others have warned, that "-Wall" really doesn't mean "all" and doesn't
catch everything that it should.

(*) That is, would have just dropped a few hit points and chalked it up to
experience.

 
 
 

A C question (about strlen)

Post by Kenny McCorma » Thu, 01 Aug 2002 06:50:33





>> There have been similar discussions about the types that off_t and
>> size_t
>> expand into.  One point of view is that they should be unsigned (as
>> size_t
>> is) because it doesn't make sense for an object to have negative size,
>> and
>> this allows for larger objects.

>The point is, though, that size_t _is_ defined as an unsigned integral
>type according to the relevant Standards.

Are you saying that once something is defined in the "relevant Standards",
people are no longer allowed to discuss it?

I heard this somewhere else recently as "Suppose they outlawed blasphemy
and then concluded that God must exist because no one has put forward any
arguments to the contrary".

 
 
 

A C question (about strlen)

Post by Erik Max Franci » Thu, 01 Aug 2002 07:41:27



> Are you saying that once something is defined in the "relevant
> Standards",
> people are no longer allowed to discuss it?

Not at all.  But surely you agree that it's essential to know how
something _is_ defined, in addition to whatever arguments one may have
on either side of how it _should_ be defined.

The fact that size_t _is_ defined as an unsigned integral type means
that such signed-unsigned mixing considerations are required, not
optional.

--

 __ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/  \ See the son in your bad day / Smell the flowers in the valley
\__/ Chante Moore
    Bosskey.net: Aliens vs. Predator 2 / http://www.bosskey.net/avp2/
 A personal guide to Aliens vs. Predator 2.

 
 
 

A C question (about strlen)

Post by phil-news-nos.. » Thu, 01 Aug 2002 17:27:19




|
|> (I know this is somewhat O/T in cup, but I prefer not to post to clc, ever)
|
| DOn't blaem you...
|
|>         int x = -10;
|>
|>         if (x > strlen("abc")) puts("Weird!");
|>         exit(0);
|> }
|>
|> Looking in the include files shows that strlen now returns unsigned, and
|> this causes the comparison to be done as unsigned.  The fix is:
|>
|>         if (x > (int) strlen("abc")) puts("Weird!");
|>
|> but I am curious as to whether there is a good way to avoid making this
|> mistake in the first place.  It sure wasn't obvious to me why one should
|> get bit for this.
|
| Why are you setting x to -10?  This strikes me as one of
| those DDT (Don't Do That) situations.

What would you suggest?  -7?

Why not just use 3 instead of strlen("abc")?

I think this is a case of someone running into a problem in a larger
program, and then working out the "minimal program" that exhibits the
same problem.  These "minimal programs" aren't necessary going to do
anything particularly useful other than show the problem.

I ran into a problem with a big program that did interactive Mandelbrot
calculations.  I eventually whittled it down to a small program snippet
that showed that strtold() gave the wrong answer.  That small program
had no other useful purpose.

--
-----------------------------------------------------------------
| Phil Howard - KA9WGN |   Dallas   | http://linuxhomepage.com/ |

-----------------------------------------------------------------

 
 
 

A C question (about strlen)

Post by Kenny McCorma » Fri, 02 Aug 2002 05:33:02





>> Are you saying that once something is defined in the "relevant
>> Standards",
>> people are no longer allowed to discuss it?

>Not at all.  But surely you agree that it's essential to know how
>something _is_ defined, in addition to whatever arguments one may have
>on either side of how it _should_ be defined.

Well, yes - I think that that it is required fits nicely into the category
of "what I learned today".

Quote:>The fact that size_t _is_ defined as an unsigned integral type means
>that such signed-unsigned mixing considerations are required, not
>optional.

Yes, and there are many skills/abilities in life that are necessary and
which we should all develop, including dealing with stupid people (and
committees).  Believe me, I'm not kidding.  Dealing with stupid things *is*
an essential life skill, as you so adeptly illustrate.
 
 
 

A C question (about strlen)

Post by Barry Margoli » Fri, 02 Aug 2002 05:21:53





>|
>|> (I know this is somewhat O/T in cup, but I prefer not to post to clc, ever)
>|
>| DOn't blaem you...
>|
>|>         int x = -10;
>|>
>|>         if (x > strlen("abc")) puts("Weird!");
>|>         exit(0);
>|> }
>|>
>|> Looking in the include files shows that strlen now returns unsigned, and
>|> this causes the comparison to be done as unsigned.  The fix is:
>|>
>|>         if (x > (int) strlen("abc")) puts("Weird!");
>|>
>|> but I am curious as to whether there is a good way to avoid making this
>|> mistake in the first place.  It sure wasn't obvious to me why one should
>|> get bit for this.
>|
>| Why are you setting x to -10?  This strikes me as one of
>| those DDT (Don't Do That) situations.

>What would you suggest?  -7?

The issue is: why compare a string length with *any* negative number?
Since it can never be negative, it seems silly.

Quote:>I think this is a case of someone running into a problem in a larger
>program, and then working out the "minimal program" that exhibits the
>same problem.  These "minimal programs" aren't necessary going to do
>anything particularly useful other than show the problem.

But if the big program is comparing string lengths with negative numbers,
it has the same design error.  Where is that number coming from, and what
sense does it make to allow it to be negative?

--

Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

 
 
 

1. A followup question to "A C question (about strlen)"

Along the same lines, but different...

On another program (not originally written by me, of course), there's the
following (pseudo-) code:

        unsigned long bytes;
        bytes = read(...);
        if (bytes != write(...)) error...;

This had been compiling just fine for years (with -Wall), until I added -W
to the gcc command line.  Now, it (correctly) flags the comparison as a
comparison of signed and unsigned.  So far, so good.  However, it occurs to
me that the real error is the declaration of "bytes" - obviously, it should
be a ssize_t.  And, you would think that if it is going to flag the
comparison (the write) as a problem, it ought also to flag the assignment
(the read), since that is equally suspicious (although it doesn't lead
directly to logic errors the way the comparison does).

So, my question is, what additional gcc warning option should I use to
more definitively catch this problem?

2. 3rd mousebutton with Kensington Orbit ???

3. i18n question (strlen or mblen)??

4. tag files for preprocessor macros?

5. strlen() question

6. Windows soon to be too expensive for the desktop?

7. strlen (Solaris 2.6) croaks on null string

8. How to structure shared /opt on Solaris

9. strlen() segfault

10. strlen bug ? kernel bug ?

11. Handling memory +printf("%s") when strlen(%s) <4

12. Kernel module development : crash when using strlen()

13. Mini-Linux Distribution Questions + General Questions + UMSDOS Questions