Pietro Cerutti said:
This is not true for the implementation of strncmp on
my system, which is:
Yes it is, under the 'as if' rule.
/*** BEGIN STRNCMP ON FREEBSD ***/
int
strncmp(s1, s2, n)
const char *s1, *s2;
size_t n;
{
if (n == 0)
return (0);
do {
if (*s1 != *s2++)
On systems where plain char is signed but unpadded,
this will find differences irrespective of whether
the bytes are treated as signed or unsigned char.
return (*(const unsigned char *)s1 -
*(const unsigned char *)(s2 - 1));
Here the unsigned char rule is applied explicitly as
required by the language specification. Note that
on your system, unsigned char promotes to int which
allows for negative results.
if (*s1++ == 0)
break;
} while (--n != 0);
return (0);}
/*** END STRNCMP ON FREEBSD ***/
I think I'm missing something about chars and/or implicit
conversions.
The problem is that plain char can be signed or unsigned.
Character codings are all non-negative, but char is only
required to be able to store positive values for characters
in the basic execution character set. So characters in the
extended character set may be negative.
Could you please explain the output of the following
program to me? The two chars c[0] and d[0] have different
values (220 and -36), are not equal (the comparison
operator returns 0) but the two strings c and d are equal
to strncmp (which returns 0) and represent the same string
to printf ("ü").
/*** BEGIN DUMMY TEST PROGRAM ***/
#include <stdio.h>
#include <string.h>
int main(void)
{
unsigned char c[2];
char d[2];
c[0] = 220; c[1] = '\0';
d[0] = c[0]; d[1] = '\0';
If plain char is signed (and 8-bits) on your system, this
will put an implementation defined value into d[0]. Most
likely is 220 - 256 == -36. The representation of -36 in
two's complement is the same as the representation of 220
in pure binary notation of an unsigned char.
printf("c is %s\n", c);
printf("d is %s\n", d);
For the reason above, this should print the same thing.
[Note that assuming character codings will make your code
non-portable.]
printf("c[0] is %02x\n", c[0]);
printf("d[0] is %02x\n", d[0]);
printf("c[0] == d[0] is %d\n", (c[0] == d[0]));
Both char and unsigned char values will promote to int
which is capable of supporting the full range of both
character types. Hence, -36 is not the same value as 220.
printf("strncmp(c, d, 1) is %d\n", strncmp(c, d, 1));
Here you are using a function which _must_ compare the
unsigned char values of the character representation.
Not surprisingly, 220 is the same as 220.
return(0);}
/*** END DUMMY TEST PROGRAM ***/