KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q38025: Signed char Type Converted to int Type at Function Call

Article: Q38025
Product(s): See article
Version(s): 4.00 5.00 5.10 | 5.10
Operating System(s): MS-DOS | OS/2
Keyword(s): ENDUSER | | mspl13_c
Last Modified: 15-NOV-1988

Question :

Any char value equal to or greater than 0x80 is printed with 0xff
preceding it when I do the following:

1. Declare an array of char and initialize it with hexadecimals.

2. Later in the program, use printf to display the values of the
   array element.

3. Use "%2x" as format string. (See sample program below.)

Why does this behavior occur?

Response:

Use "unsigned char" to declare the array "bit", or use the /J compiler
option to change the char type from its default of signed char to
unsigned char.

This is not a problem of Microsoft C Compiler. In the sample program
below, the element of array "bits" has char type, which is a signed
type in the Microsoft C compiler. In C when a variable is used as an
actual argument in a function call, usual unary data type conversion is
automatically performed before the argument is passed to the function.

In particular, signed char type is converted to int type using sign
extension (see the "Microsoft C Optimizing Compiler Language
Reference" manual for data conversion rules.) Because signed char type
can represent values from -128 to 127 (in our compiler -128 is not
defined), and a negative value is represented in two's complement form,
any hexadecimal number greater than 0x80, which is a negative value in
signed char type, will be converted to signed int type in
corresponding two's complement form.

For example, 0x80 (-128) is converted to 0xff80; 0x81 (-127) is
converted to 0xff81.

When using "printf" with unsigned hexadecimal integer control
character "%x", the values are displayed in its unsigned hexadecimal
format. If "%d" is used, the values are displayed in signed decimal
format.

The following is a sample program:

#include <stdio.h>
char bits[8] = {0x80, 0x81, 0x91, 0x00, 0x7f, 0x20, 0x40, 0x08} ;
main()
{  int i ;
   for (i=0; i<8 ; i++)
      printf("%2x ", bits[i]) ;
   printf("\n") ;
   for (i=0; i<8 ; i++)
      printf("%d ", bits[i]) ;
}

Output :
  ff80 ff81 ff91 00 7f 20 08
  -128 -127 -111 0  127 32 8

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.