tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: using the interfaces in ctype.h

[removed tech-net from reply]

On Wed, 16 Apr 2008, Greg A. Woods; Planix, Inc. wrote:
>> - cast ctype arguments to unsigned char and not int, otherwise you
>> silence the warning but you can still get a core-dump.
> If you're talking about the is*() and to*() APIs from libc then that
> doesn't seem to make any sense for a standards compatible program.

Well, strictly speaking, you should probably use two casts, like this:

        char c; /* might or might not be signed, depending on platform */
        if (isupper((int)(unsigned char)c)) ...

but what Christos suggested (casting to unsigned char) is good enough
because the standard integer promotion rules (and the relevant function
prototype, if it is in scope) will automatically add the conversion
to int.

> The definitions in all of the standards, an in the NetBSD manual
> pages, all request that the parameters for these functions are to be
> passed as (int).

Yes, the value must be passed as int.  But casting it directly to int
(without first casting to unsigned char) is wrong.  In this code:

        char c; /* might or might not be signed, depending on platform */
        if (isupper((int)c)) ...

you might have a signed char, and it might have a negative value other
than -1, and when you cast it to int you would then get a negative
integer other than -1, and that is outside the range of allowed values
for the ctype(3) functions.

> Unfortunately even various NetBSD architectures, at least for some
> releases, are inconsistent in how these interfaces are defined and
> what warnings are given for various usages.  I've had the best luck
> getting the least warnings on a wide variety of platforms by always
> casting to (int) too.

Implementations are not required to give warnings for all erroneous

--apb (Alan Barrett)

Home | Main Index | Thread Index | Old Index