Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: strcmp implementation with unsigned conversion |
| Date | 2011-05-23 12:38 -0700 |
| Organization | None to speak of |
| Message-ID | <ln62p12on7.fsf@nuthaus.mib.org> (permalink) |
| References | <7e64bfe8-e03c-4052-919b-4cd13393ef3c@q14g2000prh.googlegroups.com> |
jianhua <jhlicc@gmail.com> writes:
> 1. Why the standard* requires that values of the pair of characters
> be
> "both interpreted as unsigned char"
So that it gives consistent results for characters outside the range
0..SCHAR_MAX (commonly 0..127).
ASCII, for example, is a strictly 7-bit character set, so any values
outside the range 0..127 are not valid characters. But most other
character sets, including EBCDIC and modern ASCII-based sets such as
Latin-1 and the various Unicode representations, do have meaningful
character values above 127.
For example, the copyright sign has the code 194 (0xc2) in Latin-1. If
plain char is signed, storing the value 194 in a char object will
probably cause it to be stored as -62; if plain char is unsigned, it's
just stored as 194. By interpreting the stored value *as if* it were an
unsigned char, strcmp() consistently treats the copyright sign as being
greater than, for example, the letter 'c'. Without this requirement,
collation sequences could differ depending on whether the compiler
chooses to make plain char signed or unsigned.
In principle, I'm not sure that the semantics are entirely well defined.
In practice, it works.
> 2. Can they be both interpreted as other larger types
> eg. int, unsigned int, long, unsigned long
I'm not even sure what that means. The phrase "interpreted as" means, I
think, that the representation of the char object is treated as if it
were an unsigned char object. I don't think it makes sense to treat a
char object as something bigger than one byte.
> 3. Does "both interpreted as unsigned char" means
>
> this is wrong:
>
> int strcmp(const char *cs, const char *ct)
> {
> while (1) {
> if (*cs != *ct)
> return *cs < *ct ? -1 : 1;
> if (!*cs)
> break;
> cs++, ct++;
> }
> return 0;
> }
>
> but this is right:
>
> /*
> Copyright (C) 1991, 1992 Linus Torvalds
> */
> int strcmp(const char *cs, const char *ct)
> {
> unsigned char c1, c2;
>
> while (1) {
> c1 = *cs++; /*gcc warning: -Wconversion*/
> c2 = *ct++; /*gcc warning: -Wconversion*/
> if (c1 != c2)
> return c1 < c2 ? -1 : 1;
> if (!c1)
> break;
> }
> return 0;
> }
Yes. More precisely, the first is not portable; it works just fine if
plain char is unsigned, but it gives incorrect results if plain char is
signed and some of the values being compared exceed SCHAR_MAX.
>
> [*] 7.23.4 Comparison functions
> 1 The sign of a nonzero value returned by the comparison functions
> memcmp, strcmp, and strncmp is determined by the sign of the
> difference between the values of the first pair of characters (both
> interpreted as unsigned char) that differ in the objects being
> compared.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
strcmp implementation with unsigned conversion jianhua <jhlicc@gmail.com> - 2011-05-23 11:59 -0700
Re: strcmp implementation with unsigned conversion Keith Thompson <kst-u@mib.org> - 2011-05-23 12:38 -0700
Re: strcmp implementation with unsigned conversion Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-23 18:22 -0400
Re: strcmp implementation with unsigned conversion pete <pfiland@mindspring.com> - 2011-05-23 23:27 -0400
csiph-web