Casting not causeing sign extention
Bob Larson
blarson at oberon.UUCP
Tue Jan 21 22:31:33 AEST 1986
[This is an expantion/clarifacation of a previous article I canceled a
few hours after posting. Apologies if the cancel did not work correctly.]
In a program I am writing, I want to sign extend the eight least significant
bits of an unsigned variable to an int. Given that char is an
8-bit and signed (not a completly portable assumption, but true on the
machine in question), assigning to a char and then to an int will cause the
sign extention I want. Not wanting an extra temporary variable, I decided
that double casting would do what I want: intvar=(int)(char)unsignedvar;
Upon examining the code produced, I found the later did not work correctly.
K&R (section 2.7) and two other C compilers agree with my interpritaion.
Below is a program that tests this problem. A C compiler validation suite
should include a program that tests this use of casts. If you would like to
add a result to my table send it to me via mail, and I will repost the table
if warented.
Machine os compiler #bad of possible
Vax 750 4.2BSD cc 0 9
Prime Primos cc 19.4 0 9
QT+ os9/68k microware 1.3 9 9
--Cut here--
/* Program to test sign extention by casting, by Robert A. Larson */
/* send results to ihnp4!sdcrdcf!oberon!blarson or blarson at usc-ecl.arpa */
/* note this program assumes 8-bit characters, and character tests
are not valid otherwise */
/* note this program assumes 16-bit shorts, and short tests are not
valid otherwise */
/* if sizeof(int) != sizeof(short) && sizeof(int) != sizeof(long)
int to long expation testing should be added */
/* comment out as appropriate */
/* #define signedchar /* declaration "signed char" allowed */
#define unsigchar /* declaration "unsigned char" allowed */
#define unsigshort /* declaration "unsigned short" allowed */
#define unsiglong /* declaration "unsigned long" allowed */
main(){
int bad=0, possible=0;
char c;
#ifdef signedchar
signed char sc;
#endif
#ifdef unsigchar
unsigned char uc;
#endif
short s;
#ifdef unsigshort
unsigned short us;
#endif
int i;
unsigned u;
long l;
#ifdef unsiglong
unsigned long ul;
#endif
u=0x1ff;
c=(char)u;
if(c<0) printf("Characters are signed.\n");
if(((char)u) != c){
printf("((char)u) != c\n");
bad++;
}
possible++;
if(((int)(char)u) != (int)c){
printf("((int)(char)u) != (int)c\n");
bad++;
}
possible++;
i=(int)c;
if(((int)(char)u) != i){
printf("((int)(char)u) != i\n");
bad++;
}
possible++;
#ifdef signedchar
sc=(signed char)u;
if(sc>=0) printf("??? signed char are not signed.\n");
if(((signed char)u) != sc){
printf("((signed char)u) != sc\n");
bad++;
}
possible++;
if(((int)(signed char)u) != (int)sc){
printf("((int)(signed char)u) != (int)sc\n");
bad++;
}
possible++;
i=(int)sc;
if(((int)(signed char)u) != i){
printf("((int)(signed char)u) != i\n");
bad++;
}
possible++;
#endif
if(sizeof(int)>2){
u=0x1ffff;
s=(short)u;
if(((short)u) != s){
printf("((short)u) != s\n");
bad++;
}
possible++;
if(((int)(short)u) != (int)s){
printf("((int)(short)u) != (int)s\n");
bad++;
}
possible++;
i=(int)s;
if(((int)(short)u) != i){
printf("((int)(short)u) != i\n");
bad++;
}
possible++;
#ifdef unsigshort
us=(unsigned short)u;
if(((unsigned short)u) != us){
printf("((unsigned short)u) != us\n");
bad++;
}
possible++;
if(((int)(unsigned short)u) != (int)us){
printf("((int)(unsigned short)u) != (int)us\n");
bad++;
}
possible++;
i=(int)us;
if(((int)(unsigned short)u) != i){
printf("((int)(unsigned short)u) != i\n");
bad++;
}
possible++;
#endif
}
printf("%d bad out of a possible %d.\n",bad,possible);
}
--
Bob Larson
Arpa: Blarson at Usc-Ecl.Arpa
Uucp: ihnp4!sdcrdcf!oberon!blarson
More information about the Comp.lang.c
mailing list