char change to int, so weird.

  • Thread starter zhangsonglovexiaoniuniu
  • Start date
Z

zhangsonglovexiaoniuniu

Dear all,

I need you help.

here the program:

char a = 0x91;

printf("%x",a);

result: ff ff ff 91

now, i was confused with the result. I think it is 91. but it seems
convert to something.

why?


btw, compiler:gcc machine x86 inter
thanks
Evan
 
B

Ben Bacarisse

"(e-mail address removed)"
here the program:

Well, no. Just a fragment. A whole program is much better.
char a = 0x91;
printf("%x",a);

result: ff ff ff 91

now, i was confused with the result. I think it is 91. but it seems
convert to something.

Sort of. char is signed on your system. It can probably store numbers
between -128 and 127. 0x91 is 145 which can't be represented in a
(signed) char. At this point you enter implementation defined
territory. On my system, gcc warns me about this implicit overflow
(do you not get such a message?) and sets 'a' to a negative number
(with the bit pattern 0x91).

The 'a' argument to printf gets promoted to an int and printed in
hex. The output you see is the correct output for the negative number
you are printing.

The simplest solution is to declare 'a' as 'unsigned char a;'. 145
will then fit and get printed as you expect.

BTW. I thought this would be a FAQ, but I searched and could not find
it. Maybe someone with more familiarity can find it -- surely it is
in there?
 
Z

zhangsonglovexiaoniuniu

"(e-mail address removed)"



Well, no. Just a fragment. A whole program is much better.




Sort of. char is signed on your system. It can probably store numbers
between -128 and 127. 0x91 is 145 which can't be represented in a
(signed) char. At this point you enter implementation defined
territory. On my system, gcc warns me about this implicit overflow
(do you not get such a message?) and sets 'a' to a negative number
(with the bit pattern 0x91).

The 'a' argument to printf gets promoted to an int and printed in
hex. The output you see is the correct output for the negative number
you are printing.

The simplest solution is to declare 'a' as 'unsigned char a;'. 145
will then fit and get printed as you expect.

BTW. I thought this would be a FAQ, but I searched and could not find
it. Maybe someone with more familiarity can find it -- surely it is
in there?

i understand what you said , but another question:
if it is overflow why the value should be bit pattern?
is it a rule or something else?
 
J

Jack Klein

"(e-mail address removed)"


Well, no. Just a fragment. A whole program is much better.


Sort of. char is signed on your system. It can probably store numbers
between -128 and 127. 0x91 is 145 which can't be represented in a
(signed) char. At this point you enter implementation defined
territory. On my system, gcc warns me about this implicit overflow
(do you not get such a message?) and sets 'a' to a negative number
(with the bit pattern 0x91).

The 'a' argument to printf gets promoted to an int and printed in
hex. The output you see is the correct output for the negative number
you are printing.

Correction, there is no "correct output" for his printf() statement,
since it produces undefined behavior. He is using the "%x" conversion
specifier, which requires an unsigned int parameter. But he is
passing a signed int with a negative value.

Argument compatibility in *printf() between signed and unsigned types
is guaranteed only when the value is within the range of both types,
and that is never true when passing a signed type with a negative
value to match an unsigned type conversion specifier.

It would be the correct output for:

printf("%x", (unsigned int)a);
The simplest solution is to declare 'a' as 'unsigned char a;'. 145
will then fit and get printed as you expect.

BTW. I thought this would be a FAQ, but I searched and could not find
it. Maybe someone with more familiarity can find it -- surely it is
in there?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
M

Martin Ambuhl

Dear all,

I need you help.

here the program:

char a = 0x91;

printf("%x",a);

Well, no. That isn't anywhere close to being a program.
result: ff ff ff 91

Well, no. I don't believe those three embedded spaces for a minute.
now, i was confused with the result. I think it is 91. but it seems
convert to something.

why?

This results from (a) 'char' being signed on your implementation and
(b) sign extension when 0x91 has the same bit pattern as a negative
char, which then is promoted to a negative int when passed to printf.

The program below, which incorporates several things which should never
appear in well-written code, should illustrate the problem if you
examine the program and the output. Note
(1) This is a horrid program and should not be a model for anything you
will ever write, and
(2) The output reported below the program listing is for one
implementation. There is no way for me to predict what your
implementation will actually do with it.

#include <stdio.h>

int main(void)
{
/* note that 'char' may be either unsigned or signed */
unsigned char a = 0x91;
signed char b = 0x91; /* possible overflow */
unsigned int c;
signed int d;

printf
("note that each attempt to print an unsigned value using
\"%%x\"\n"
"is dodgy and should not, in fact, be done.\n\n");

printf("unsigned char a as (unsigned) hex = %x\n", a);
printf("signed char b as (unsigned) hex = %x\n\n", b);
c = a;
d = a;
printf
("unsigned int c and signed int d assigned (unsigned char) 0x91\n"
"unsigned int c as (unsigned) hex = %x\n"
"signed int d as (unsigned) hex = %x\n\n", c, d);
c = b;
d = b;

printf
("unsigned int c and signed int d assigned (signed char) 0x91\n"
"unsigned int c as (unsigned) hex = %x\n"
"signed int d as (unsigned) hex = %x\n\n", c, d);
return 0;
}

[output on one implementation]
note that each attempt to print an unsigned value using "%x"
is dodgy and should not, in fact, be done.

unsigned char a as (unsigned) hex = 91
signed char b as (unsigned) hex = ffffff91

unsigned int c and signed int d assigned (unsigned char) 0x91
unsigned int c as (unsigned) hex = 91
signed int d as (unsigned) hex = 91

unsigned int c and signed int d assigned (signed char) 0x91
unsigned int c as (unsigned) hex = ffffff91
signed int d as (unsigned) hex = ffffff91
 
B

Ben Bacarisse

Jack Klein said:
Correction, there is no "correct output" for his printf() statement,
since it produces undefined behavior. He is using the "%x" conversion
specifier, which requires an unsigned int parameter. But he is
passing a signed int with a negative value.

Yes, thanks. I forget %x is for unsigned.
Argument compatibility in *printf() between signed and unsigned types
is guaranteed only when the value is within the range of both types,

Where does this special leeway come from? In paragraph 9 of the
fprintf section its says:

"If any argument is not the correct type for the corresponding
conversion specification, the behavior is undefined."
 
B

Bryan

printf
("note that each attempt to print an unsigned value using
\"%%x\"\n"
"is dodgy and should not, in fact, be done.\n\n");

ITYM signed, or possibly negative signed value ?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top