INFO: Promotion of char to int May Add Two Hex Digits in printf

ID: Q69344


The information in this article applies to:
  • Microsoft C for MS-DOS, versions 6.0, 6.0a, 6.0ax
  • Microsoft C for OS/2, versions 6.0, 6.0a
  • Microsoft C/C++ for MS-DOS, version 7.0
  • Microsoft Visual C++ for Windows, 16-bit edition, versions 1.0, 1.5
  • Microsoft Visual C++, 32-bit Editions, versions 1.0, 2.0, 4.0, 5.0, 6.0


SUMMARY

When you try to display a signed character in two-digit hexadecimal format as follows:


char hex_byte = 0x80;
printf( "The Hex value is %X", hex_byte); 
four digits are displayed if the character has a value of 0x80 to 0xFF because of promotion of the character to a signed int. Under Windows NT, eight digits will be displayed because of the integer size difference. The %x and %X specifiers designate an unsigned hexadecimal integer, but because leading 0s (zeros) are dropped, values in the range of 0 to 127 produce the desired two digits. See the sample code below.

To preserve the two-digit display for all possible values, typecast the character to an unsigned character in the printf() argument list, as shown below:

   printf( "The hex value is %X", (unsigned char)hex_byte); 
Another way to achieve this, if sign is of no consequence, is to declare the variables as unsigned character.


MORE INFORMATION

For ANSI compliance, the compiler promotes all character arguments to signed int. If the type is signed character, then the value will be sign- extended. Thus, the int will be negative if the left-most bit of the character was set, resulting in a different value for the int. When an unsigned character is promoted, a 0 (zero) is placed in the high byte so that the value is retained.

This promotion may also cause problems with comparisons of signed and unsigned characters. This situation, unlike the printf() situation, will produce a C4018 (signed/unsigned mismatch) warning at warning level 3 and above, beginning with C version 6.0.

Sample Code


/* Compile options needed: none
*/ 

#include <stdio.h>

void main( void)
{
   char goo = 127;
   char myvar = 128;

   printf( "goo = %X\n",   goo); /* yields "7F" */ 
   printf( "myvar = %X\n",   myvar); /* yields "FF80" or "FFFFFF80"*/ 

   /* Correct way to represent the char as two hex digits "80". */ 
   printf( "myvar = %X\n",   (unsigned char)myvar);
} 

Additional query words: conversion

Keywords : kbcode kbLangC kbVC100 kbVC150 kbVC200 kbVC400 kbVC500 kbVC600
Version : MS-DOS:6.0,6.00a,7.0; OS/2:6.0,6.00a; WINDOWS:1.0,1.5; WINDOWS NT:1.0,2.0,4.0,5.0
Platform : MS-DOS NT OS/2 WINDOWS
Issue type : kbinfo


Last Reviewed: July 1, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.