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

Last reviewed: October 3, 1997
Article ID: Q38025

The information in this article applies to:
  • The C Run-time (CRT) included with: - Microsoft C for MS-DOS, versions 5.1, 6.0, 6.0a, 6.0ax - Microsoft C for OS/2, versions 5.1, 6.0, 6.0a - Microsoft C/C++ for MS-DOS, version 7.0 - Microsoft Visual C++ for Windows, versions 1.0, 1.5 - Microsoft Visual C++ 32-bit Edition, versions 1.0, 2.0, 4.0, 5.0

SUMMARY

Any char value equal to or greater than 0x80 is printed with 0xFF or 0xFFFFFF preceding it when the following steps are done:

  1. An array of char is declared and initialized.

  2. Later in the program, printf() is used to display the values of the array element.

  3. "%2x" is used as a format string. (See sample program below.)

MORE INFORMATION

The unsigned char type should be used when declaring the array or the /J compiler option should be used to change the char type from its default of signed char to unsigned char. Whether or not 0xFF or 0xFFFFFF is printed depends on the size of an integer on the host system.

This is not a problem with the Microsoft C Compiler. In the sample program below, the array called bits consists of elements of type char. By default, the char type is a signed type in Microsoft C. 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, the signed char type is converted to the int type using sign extension (see the Microsoft C Optimizing Compiler Language Reference manual for data conversion rules.) Because the signed char type can represent values from -128 to 127, and a negative value is represented in two's complement form, any hexadecimal number greater than 0x80, which is a negative value in a signed char type, will be converted to a signed int type in corresponding two's complement form.

For example, on systems with 16-bit integers, 0x80 (-128) is converted to 0xFF80; 0x81 (-127) is converted to 0xFF81. On systems where integers are 32-bits in size, 0x80 is converted to 0xFFFFFF80 and 0x81 is converted to 0xFFFFFF81.

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

Sample Code

   /* Compiler options needed: none
   */

   #include <stdio.h>

   char bits[8] = {0x80, 0x81, 0x91, 0x00, 0x7f, 0x20, 0x40, 0x08} ;

   void 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 on systems with 16-bit integers:

   ff80 ff81 ff91  0 7f 20 40  8
   -128 -127 -111 0 127 32 64 8

Output on systems with 32-bit integers:

   ffffff80 ffffff81 ffffff91  0 7f 20 40  8
   -128 -127 -111 0 127 32 64 8
Keywords          : CRTIss kbfasttip
Version           : MS- DOS:5.1,6.0,6.00a,6.00ax,7.0;OS/2:5.1,6.0,6.00a;WIN3X:1.0,1.5;WINNT:1.0,2.0 ,4.0,5.0;
Platform          : MS-DOS NT OS/2 WINDOWS


================================================================================


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.

Last reviewed: October 3, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.