Skip to Content.
Sympa Menu

freetds - Re: [freetds] casts and warnings

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "James K. Lowden" <jklowden AT schemamania.org>
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] casts and warnings
  • Date: Wed, 9 Mar 2005 19:21:26 -0500

On Wed, 09 Mar 2005 16:15:44 -0500, entropy AT freetds.org wrote:
>
> > Moreover, the whole point of isspace(3) is to test a char -- almost
> > always a signed char, because ASCII defines 7-bit characters. The
> > code as written was completely reasonable, normal, standard C idiom.
>
> Wrong. The code is correct with the cast and incorrect without it. The
>
> calling code needs to ensure that when *p is sign extended it will be a
> positive integer. ASCII may define 7-bit characters but char is an
> 8-bit datatype and can be negative on systems with signed chars.
>
> Quoting the SUS that you cited, emphasis added:
>
> In all cases c is an int, the value of which must be a character
> ***representable as an unsigned char*** or must equal the value of the
> macro EOF. If the argument has any other value, the behaviour is
> undefined.
>
> Clearly a negative signed char is not representable as an unsigned char,
>
> so we need to ensure that we never pass such a value to isspace().

You're referring to isspace(3) in particular:

http://www.opengroup.org/onlinepubs/7990989775/xsh/isspace.html

(I would love to know what compiler issued what warning. I doubt the
compiler knew about isspace(3)'s peculiar unsigned char restriction.)

As I read it, the programmer is obliged to ensure 0 <= c <= 255. Casting
a negative value to unsigned char achieves that in only the narrowest of
technical senses. 0xff == 0xff, but -1 != 255. Redefining the bits
doesn't guard against bad inputs; it merely treats a bad input as
something it's not.

To do what you want, we'd do something like this:

for (p+=2; *p >= 0 && isspace(*p); p++) {
...
}
if (*p < 0) {
/* log error */
return 0; /* or whatever */
}

I think that's overkill, and I think every isspace(3) implementation will
return zero for any negative value in every locale. But at least we're
not pretending:

(unsigned char) *p == 128 + (0x7F & *p)

As far as C is concerned, I assume we agree that as long as *p is
nonnegative, no cast is needed or desired to promote char to int.

--jkl







Archive powered by MHonArc 2.6.24.

Top of Page