Barry Schwarz wrote:
On Wed, 11 Jun 2008 11:30:43 -0400, Eric Sosman <Er*********@su n.com>
wrote:
>Barry Schwarz wrote:
>>On Tue, 10 Jun 2008 22:32:28 -0700 (PDT), Steven
<mi********@h otmail.comwrote :
Hello, everyone!
I find a version of strcpy(), I don't know why it return the unsigned
char value.
In discussing integer conversions, paragraph 6.3.1.8 says that if the
operands have the same type, no conversion is performed.
No, it says that if the *promoted* operands have the same
type, no conversion is performed.
>>Both
operands in your subtraction have type unsigned char. Therefore,
unsigned subtraction is performed.
No. `unsigned char' operands promote to `int' (on most
systems) or to `unsigned int' (if UCHAR_MAX INT_MAX), so
the implementation determines whether signed (usually) or
unsigned (sometimes) arithmetic is used.
True, I obviously missed the lead-in paragraph in searching for the
conversion rules.
Which raises the question of why the OP believes that his function is
returning an unsigned value.
Clearly it doesn't, and the O.P. is confused about the
"usual arithmetic conversions."
The function as shown is a work-alike for the standard
strcmp() on machines where unsigned char promotes to (signed)
int, and works *because* the promotion is to a signed type:
That's why the subtraction produces a negative value, as
required, when *s1 < *s2. Specifically, the function's
return *(unsigned const char *)s1
- *(unsigned const char *)(s2);
.... is evaluated as if it had been written
return (int)(*(unsigne d const char*)s1)
- (int)(*(unsigne d const char*)s2);
On those (rarer) machines where unsigned char promotes
to unsigned int, the function as shown is still all right in
the presence of a few additional guarantees, namely, that
conversion of a too-large unsigned int value to signed int
type doesn't trap or do anything weird, but silently produces
a negative value as is common on two's-complement machines.
On these machines the operation is equivalent to
return (int)(
(unsigned int)(*(unsigned const char*)s1)
- (unsigned int)(*(unsigned const char*)s2) );
.... and we rely on "helpful" behavior when out-of-range unsigned
values are converted to signed int.
On the (nonexistent?) machines where unsigned char promotes
to unsigned int and where the conversion of large unsigned int
values to signed int does Weird Stuff, the function as shown
would not work: The Weird Stuff would occur whenever the s1
string was less than the s2 string. On such a system you'd
need something like one of the conditionals shown elsethread.
--
Er*********@sun .com