[freetds] casts and warnings

James K. Lowden jklowden at schemamania.org
Wed Mar 9 19:21:26 EST 2005


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





More information about the FreeTDS mailing list