char, unsigned char, signed char
Author |
Message |
John Li #1 / 25
|
 char, unsigned char, signed char
Since these three types are distinct, what ramifications are there for real programs? Does anyone ever really use signed char for anything? And how many implementations out there don't make char behave the same way as signed char anyway? Also, I don't know if I remember correctly, but I thought I heard once that on some systems, unsigned chars or ints are slower to operate on than their signed, or maybe plain in the case of char, counterparts. Is this true, and if so, why is that? Thanks in advance...
|
Sat, 23 Nov 2002 03:00:00 GMT |
|
 |
Mark A. Odel #2 / 25
|
 char, unsigned char, signed char
Quote: >Since these three types are distinct, what ramifications are there for >real programs? Does anyone ever really use signed char for anything? And >how many implementations out there don't make char behave the same way as >signed char anyway? >Also, I don't know if I remember correctly, but I thought I heard once >that on some systems, unsigned chars or ints are slower to operate on than >their signed, or maybe plain in the case of char, counterparts. Is this >true, and if so, why is that? >Thanks in advance...
char is determined by your compiler to be either signed char or unsigned char. You can usually state which way you want it to behave. For the 8051, which has no notion of sign, unsigned chars are more efficient than signed chars. Thus, most 8051 C compilers default their char type to unsigned char.
|
Sat, 23 Nov 2002 03:00:00 GMT |
|
 |
Juergen Hein #3 / 25
|
 char, unsigned char, signed char
Quote:
>Since these three types are distinct, what ramifications are there for >real programs? Does anyone ever really use signed char for anything? And >how many implementations out there don't make char behave the same way as >signed char anyway?
[...] On AIX the, at least the last time I had the fun to play with, the default type of char was (is) unsigned. Now can this be a problem ? Yes 8-) - one might end up with 255 instead of -1, quite a difference so see before as for some code I actually used "signed char ..." and "unsigned char ...". Better safe than sorry. Quote: >Also, I don't know if I remember correctly, but I thought I heard once >that on some systems, unsigned chars or ints are slower to operate on than >their signed, or maybe plain in the case of char, counterparts. Is this >true, and if so, why is that?
[...] Yes, although it might be CPU model specific. E.g. on Intel machines unsigned can be a wee bit faster than signed but for the why one needs to ask the CPU designers I guess. It is not a C problem but valid on the assembler level. Now we are talking about nanoseconds here, so ... Cheers, Juergen -- \ Real name : Jrgen Heinzl \ no flames /
|
Sat, 23 Nov 2002 03:00:00 GMT |
|
 |
Jack Klei #4 / 25
|
 char, unsigned char, signed char
On Tue, 6 Jun 2000 13:47:09 -0700, John Lin
Quote: > Since these three types are distinct, what ramifications are there for > real programs? Does anyone ever really use signed char for anything? And > how many implementations out there don't make char behave the same way as > signed char anyway? > Also, I don't know if I remember correctly, but I thought I heard once > that on some systems, unsigned chars or ints are slower to operate on than > their signed, or maybe plain in the case of char, counterparts. Is this > true, and if so, why is that? > Thanks in advance...
Any project that I work on where I have any say in the coding guidelines, which is all of them, and has been for quite some time, prohibits the use of char other than when required by standard library or third-party library functions. All char variables defined and used in internal code for the project are required to be defined as either signed or unsigned specifically, usually using a typedef of some sort. Jack Klein -- Home: http://jackklein.home.att.net
|
Sat, 23 Nov 2002 03:00:00 GMT |
|
 |
Ben Pfaf #5 / 25
|
 char, unsigned char, signed char
Quote:
> Any project that I work on where I have any say in the coding > guidelines, which is all of them, and has been for quite some time, > prohibits the use of char other than when required by standard library > or third-party library functions.
Don't you find that this requires a lot of casts to char * when calling out to standard library functions? If I could avoid that difficulty then I wouldn't ever use char either.
|
Sat, 23 Nov 2002 03:00:00 GMT |
|
 |
Richard Heathfiel #6 / 25
|
 char, unsigned char, signed char
Quote:
> Since these three types are distinct, what ramifications are there for > real programs? Does anyone ever really use signed char for anything? And > how many implementations out there don't make char behave the same way as > signed char anyway? > Also, I don't know if I remember correctly, but I thought I heard once > that on some systems, unsigned chars or ints are slower to operate on than > their signed, or maybe plain in the case of char, counterparts. Is this > true, and if so, why is that? > Thanks in advance...
EBCDIC is an 8-bit code, with the digits and (IIRC) most or all of the letters being contained within the region 0x80 to 0xFF. The C Standard requires that the entire character set be representable as positive values of char. Therefore, systems using EBCDIC default to unsigned char. These include VM/CMS and OS/390 (used to be called MVS). Those not using mainframe systems often seem to think mainframes don't run C programs. I can tell you from bitter experience that mainframe C programs are in fact relatively common. -- Richard Heathfield "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999. C FAQ: http://www.eskimo.com/~scs/C-faq/top.html 37 K&R Answers: http://users.powernet.co.uk/eton/kandr2/index.html (60 to go)
|
Sun, 24 Nov 2002 03:00:00 GMT |
|
 |
Andreas Klima #7 / 25
|
 char, unsigned char, signed char
Quote:
> Since these three types are distinct, what ramifications are there for > real programs? Does anyone ever really use signed char for anything? And > how many implementations out there don't make char behave the same way as > signed char anyway? > Also, I don't know if I remember correctly, but I thought I heard once > that on some systems, unsigned chars or ints are slower to operate on than > their signed, or maybe plain in the case of char, counterparts. Is this > true, and if so, why is that? > Thanks in advance...
#include <stdio.h> main() { char x = 139; printf("%d\n", (int)x); Quote: }
you will get -117 if you take unsigned char you will get 139. this sounds trivial but remember that EOF is defined by -1. if you have unsigend char, this will be represented as 255 so a statement like unsigned char c; while ((c = getchar()) != EOF) will never end. (BTW getchar() is defined to returning an int, not a char, this is only an example) -- Greetings from Lake Constance, Germany
|
Sun, 24 Nov 2002 03:00:00 GMT |
|
 |
Bo #8 / 25
|
 char, unsigned char, signed char
Quote: >> Since these three types are distinct, what ramifications are there for >> real programs? Does anyone ever really use signed char for anything? And >> how many implementations out there don't make char behave the same way as >> signed char anyway?
The rule of thumb is to ONLY use char whenever you are absolutely sure it will always represent a character (like a-z, 0-9, punctuation, whitespace, etc.) It will be portable in that instance ONLY. If you are ever using it for data, declare it signed or unsigned becuase it doesn't hurt anyway. I used a signed char that represented height for a raised button. It could be positve(up) or negative(pressed), and it needed to be as small as possible because the function call was being sent over a USB link on an embedded system, where the smaller the better. There are probably many other uses I assume, I haven't personally had to use it for anything else, but then again I haven't been programming very long.
|
Sun, 24 Nov 2002 03:00:00 GMT |
|
 |
Jack Klei #9 / 25
|
 char, unsigned char, signed char
comp.lang.c: Quote:
> > Any project that I work on where I have any say in the coding > > guidelines, which is all of them, and has been for quite some time, > > prohibits the use of char other than when required by standard library > > or third-party library functions. > Don't you find that this requires a lot of casts to char * when > calling out to standard library functions? If I could avoid that > difficulty then I wouldn't ever use char either.
That's why I said "other when required by standard library ... functions". That minimizes, but does not eliminate, the amount of casting required. I've been through too many situations where an application was moved to a different compiler and/or platform where the default char type changed, especially back in the old days when a compiler option to specify your choice was not as widely available as it is today. Come to think of it, I remember porting from between compilers with different choices way back in the pre-Standard K&R1 days, when there was only one type of char, and you had no choice about whether it was signed or unsigned. Some of the resulting bugs were subtle and extremely hard to track down. The extra casts are well worth the price is there is a greater than 0% chance the code will ever be ported. Jack Klein -- Home: http://jackklein.home.att.net
|
Sun, 24 Nov 2002 03:00:00 GMT |
|
 |
Christian B #10 / 25
|
 char, unsigned char, signed char
In article
Quote:
> Since these three types are distinct, what ramifications are there for > real programs? Does anyone ever really use signed char for anything?
What would you use to store 10,000,000 values that are guaranteed to be in the range from -20 to +20? Quote: > And > how many implementations out there don't make char behave the same way as > signed char anyway?
Some, but not all. Quote: > Also, I don't know if I remember correctly, but I thought I heard once > that on some systems, unsigned chars or ints are slower to operate on than > their signed, or maybe plain in the case of char, counterparts. Is this > true, and if so, why is that?
On some systems, unsigned char operations are slower than signed char, and on other systems, they are faster. It is quite likely that the compiler chooses char to be the faster variety, if there is a difference. Some compilers can be configured to make plain char either signed or unsigned.
|
Sun, 24 Nov 2002 03:00:00 GMT |
|
 |
Dan P #11 / 25
|
 char, unsigned char, signed char
Quote: >Since these three types are distinct, what ramifications are there for >real programs?
Use plain char for string manipulation purposes. Use signed char when you need small signed integers. Use unsigned char when you need small unsigned integers or to treat a memory block as a sequence of bytes. Quote: >Does anyone ever really use signed char for anything?
See above. Quote: >And how many implementations out there don't make char behave the >same way as signed char anyway?
Plenty of them. Out of the 4 first C implementations mentioned in K&R1, some had char as an unsigned type. Nowadays, most RISC implementations have plain char as an unsigned type, the most notable exception being those for Alpha. Quote: >Also, I don't know if I remember correctly, but I thought I heard once >that on some systems, unsigned chars or ints are slower to operate on than >their signed, or maybe plain in the case of char, counterparts. Is this >true, and if so, why is that?
Most current processors use two's complement representation for signed integers. One of the properties of this representation is that the very same instructions are used for both signed and unsigned arithmetic, it's only comparisons that are performed differently (but usually with the same speed). The reason for having the signedness of char left unspecified is the performance of promoting a char to an int, which is needed whenever a char is involved in some arithmetic operations. On some processors, the fastest way to do that is with a sign extent instruction, hence the default char as a signed type on implementations for these processors. As already mentioned in the thread, some character sets impose default char to be an unsigned type, regardless of any hardware considerations. And now a trivia quiz. The following code is the memccpy() implementation from glibc. Can you spot the bug? /* Copy no more than N bytes of SRC to DEST, stopping when C is found. Return the position in DEST one byte past where C was copied, or NULL if C was not found in the first N bytes of SRC. */ void * memccpy (dest, src, c, n) void *dest; const void *src; int c; size_t n; { register const char *s = src; register char *d = dest; register const int x = (unsigned char) c; register size_t i = n; while (i-- > 0) if ((*d++ = *s++) == x) return d; return NULL; } I have already reported the bug and it is fixed in the upcoming glibc 2.2. Dan -- Dan Pop CERN, IT Division
Mail: CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland
|
Sun, 24 Nov 2002 03:00:00 GMT |
|
 |
karl malbrai #12 / 25
|
 char, unsigned char, signed char
Quote: > In article
> > Since these three types are distinct, what ramifications are there for > > real programs? Does anyone ever really use signed char for anything? > What would you use to store 10,000,000 values that are guaranteed to be in > the range from -20 to +20?
Be careful... As things in themselves, I'd use 41 COUNTERS of size long for the values. Karl M
|
Sun, 24 Nov 2002 03:00:00 GMT |
|
 |
Keith Thompso #13 / 25
|
 char, unsigned char, signed char
Quote:
[...] > > What would you use to store 10,000,000 values that are guaranteed to be in > > the range from -20 to +20? > Be careful... As things in themselves, I'd use 41 COUNTERS of size long for > the values. Karl M
Then you're not storing 10,000,000 values. --
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst> Welcome to the last year of the 20th century.
|
Sun, 24 Nov 2002 03:00:00 GMT |
|
 |
Gilford Wimbl #14 / 25
|
 char, unsigned char, signed char
Quote: >And now a trivia quiz. The following code is the memccpy() >implementation from glibc. Can you spot the bug? > /* Copy no more than N bytes of SRC to DEST, stopping when C is found. > Return the position in DEST one byte past where C was copied, or > NULL if C was not found in the first N bytes of SRC. */ > void * > memccpy (dest, src, c, n) > void *dest; const void *src; > int c; size_t n; > { > register const char *s = src; > register char *d = dest; > register const int x = (unsigned char) c; > register size_t i = n; > while (i-- > 0) > if ((*d++ = *s++) == x) > return d; > return NULL; > }
I think I can see it (thanks to your discussion leading up to it). x will always be positive, because c is cast to unsigned before the assignment. But *d and *s could be negative if the default char type is signed. Hence, the loop might not stop where it is supposed to if the value of c as a signed char is negative and the default char type is signed. What is the best way to fix it? Like this? /* Copy no more than N bytes of SRC to DEST, stopping when C is found. Return the position in DEST one byte past where C was copied, or NULL if C was not found in the first N bytes of SRC. */ void * memccpy (dest, src, c, n) void *dest; const void *src; int c; size_t n; { register const unsigned char *s = src; register unsigned char *d = dest; register const int x = (unsigned char) c; register size_t i = n; while (i-- > 0) if ((*d++ = *s++) == x) return d; return NULL; } Quote: >I have already reported the bug and it is fixed in the upcoming glibc 2.2. >Dan >-- >Dan Pop >CERN, IT Division
>Mail: CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland
regards, GW
|
Mon, 25 Nov 2002 03:00:00 GMT |
|
 |
Gilford Wimbl #15 / 25
|
 char, unsigned char, signed char
[snip] Quote: >And now a trivia quiz. The following code is the memccpy() >implementation from glibc. Can you spot the bug? > /* Copy no more than N bytes of SRC to DEST, stopping when C is found. > Return the position in DEST one byte past where C was copied, or > NULL if C was not found in the first N bytes of SRC. */ > void * > memccpy (dest, src, c, n) > void *dest; const void *src; > int c; size_t n; > { > register const char *s = src; > register char *d = dest; > register const int x = (unsigned char) c; > register size_t i = n; > while (i-- > 0) > if ((*d++ = *s++) == x) > return d; > return NULL; > }
I think I can see it (thanks to your discussion leading up to it). x will always be positive, because c is cast to unsigned before the assignment. But *d and *s could be negative if the default char type is signed. Hence, the loop might not stop where it is supposed to if the value of c as a signed char is negative and the default char type is signed. What is the best way to fix it? Like this? /* Copy no more than N bytes of SRC to DEST, stopping when C is found. Return the position in DEST one byte past where C was copied, or NULL if C was not found in the first N bytes of SRC. */ void * memccpy (dest, src, c, n) void *dest; const void *src; int c; size_t n; { register const unsigned char *s = src; register unsigned char *d = dest; register const int x = (unsigned char) c; register size_t i = n; while (i-- > 0) if ((*d++ = *s++) == x) return d; return NULL; } Quote: >I have already reported the bug and it is fixed in the upcoming glibc 2.2. >Dan >-- >Dan Pop >CERN, IT Division
>Mail: CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland
regards, GW
|
Mon, 25 Nov 2002 03:00:00 GMT |
|
|
Page 1 of 2
|
[ 25 post ] |
|
Go to page:
[1]
[2] |
|