[snips]
This is not at all obvious. I would never get that idea.
No? Yet the functions as defined _cannot_ accept a legitimately sized
buffer (ints being too small) but *can* accept negative values.
Obviously, the requirement to take negatives was so compelling that it
overrode the ability to handle perfectly valid sizes; there _must_ be
"magic" involved, else there would be no such compelling reason.
It doesn't imply that to me. Not all all representable input values are
useful.
No, they're not. On a system with 64-bit ints, one could reasonably
assume it is most unlikely they'd have buffers as large as 2^63-1. On a
16-bit system, by contrast, ints are not large enough to handle useful
sizes - yet he uses ints. Thus, again, the "magic" triggered by negative
values must be sufficiently compelling it outweighs the cost of losing
support for perfectly legitimate buffers. Again I ask, what _is_ that
magic?
What magic happens when you pass a negative value (except EOF) or a
positive value > UCHAR_MAX to one of the ctype isxxx functions?
Presumably none at all, but then on all but some relatively odd systems,
the issue never comes up, as these functions are not excluding legitimate
values in the process.
The correct comparison would be to ask why, if the character set contains
values from 0..255, would anyone design the is_xxx functions to accept
values from, say, -17 to 192? Doing so excludes perfectly legitimate
values, so there must be a compelling reason to do so... and it is done to
allow a greater range of negative values, meaning there must be a
compelling reason to allow those, to the exclusion of legitimate values.
The is_xxx functions do not work this way. They allow the full range of
legitimate values (with some hoofooraw when it comes to 32-bit chars,
32-bit ints, and where EOF fits in) but they do not go out of their way to
exclude legitimate options for the sake of undescribed magic.
What
magic happens if you pass a value outside of [-1.0, 1.0] to an arcsine
function? You'll have to check the documentation.
Again, does the arcsin function clip its input range, to reject legitimate
sensible values for no particular reason? Let's see... nope, it's defined
in terms of values _between_ -1 and 1, so it would not be excluding
legitimate values if it allows passing in (with bogus results or
otherwise) of a larger range.
You fail to compare cases. Your exemplars involve functions which accept
the entire legitimate range of possible values, then you ask what happens
beyond those ranges?
That is not the case with MM's code. MM's code *excludes* perfectly
legitimate values. Why? Oh, right, to use ints instead of size_ts. Why
would one want to use ints over size_ts, when dealing with buffers and
sizes? One wouldn't - unless there were a really compelling reason to
accept negative values, to the exclusion of perfectly legitimately sized
buffers outside the range an int can store.
He does not present that compelling reason, though; it is "magic" and one
is, presumably, supposed to simply guess at what the magic is.
I don't need a justification for using a signed type.
You do if, in the process of using it, you limit the range of perfectly
valid inputs for no good reason.
I need a
justification for using an unsigned type. And "it cannot be negative"
isn't enough justification for me.
I see. So you're the sort who would write code as he does, with ints
instead of size_ts as size values.
Very good, and when a legitimate buffer needs to use your functions, but
can't, because you've used an int instead of a size_t and the size can
no longer be passed in?
Oh, right, your code's as broken as his as a result, and should be turfed
along with his.
Yes, but that would be true just the same if he had used "unsigned int".
Who the hell said unsigned int? Granted, it would be an improvement
over his abortion, but it's largely irrelevant - we're talking about
negative values, or, rather, the complete lack of justification for them
in a context where the proper type to use is a size_t.
Again: There are good reasons to use size_t for buffer sizes (mostly
that it is large enough to hold all possible buffer sizes, but also that
using a standard type serves as documentation), so I would use size_t.
But there is only a weak reason to use unsigned int
Then don't use it. Use the *proper* type - size_t.
(it cannot be
negative) which doesn't outweigh the disadvantages of unsigned types,
for example:
* you cannot naturally count down to zero:
for (i = n; i >= 0; i--)
Check MM's code. He's got a loop in there:
for ( i = 0; i < len; i++ )
but len, if passed in a legitimate value for the size of a buffer, just
one too large for an int, may well result in len being less than zero. So
signed doesn't buy anything here, either, and the objections to using the
correct types don't add up.
* comparison between signed and unsigned values isn't value-preserving:
And the effects of signed integer overflow are...? As in the code he
presents, using the wrong type?
Actually, the prototype says you can only pass an int. The point about
"you cannot pass a char" is that if you come across code like
char c; .... isspace(c) ...
or
char *s; ... isspace(*s) ...
there is a very high probability that this is a bug.
Quite possibly, unless you happen to be *damned* sure of the source of the
data - which is, in fact, not likely to be all that often.
Still, if you _are_ sure the data is in the legitimate range, you _can_
"pass a char to the isxxx functions", in direct contradiction of what he
said. What you cannot do is blithely assume that _all_ characters passed
will have values in the range the isxxx functions will accept, unless you
take steps to ensure they are, in fact, representable as an unsigned char
or EOF. But that's not what he said; he said you can't pass chars to the
functions; this is simply wrong. You can.
Except that on somebody else's systems the chars _are not_ in that
range, and your program will crash or - worse - produce some slightly
wrong output.
As I said, as long as the chars *are* in that range, pass 'em in,
everyone's happy.
What is it today? You're at least the third person who seems to prefer to
read something which has absolutely nothing to do with what was written,
and you've done so several times in one post.
You *can* pass chars to isxxx, as long as those chars are in range.
The question of types was not about *extending* the range, but of
*limiting* it.
The question of types was not about "unsigned int", but the inclusion of
negatives for no reason, to the exclusion of legitimate ranges... none of
your exemplars remotely relate.