Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > char change to int, so weird.

Reply
Thread Tools

char change to int, so weird.

 
 
zhangsonglovexiaoniuniu@gmail.com
Guest
Posts: n/a
 
      12-07-2007
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
 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      12-07-2007
"(E-Mail Removed)"
<(E-Mail Removed)> writes:

> 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?

--
Ben.
 
Reply With Quote
 
 
 
 
zhangsonglovexiaoniuniu@gmail.com
Guest
Posts: n/a
 
      12-07-2007
On 12月7日, 上午11时38分, Ben Bacarisse <(E-Mail Removed)> wrote:
> "(E-Mail Removed)"
>
> <(E-Mail Removed)> writes:
> > 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?
>
> --
> Ben.


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?
 
Reply With Quote
 
Jack Klein
Guest
Posts: n/a
 
      12-07-2007
On Fri, 07 Dec 2007 03:38:22 +0000, Ben Bacarisse
<(E-Mail Removed)> wrote in comp.lang.c:

> "(E-Mail Removed)"
> <(E-Mail Removed)> writes:
>
> > 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.


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
 
Reply With Quote
 
Martin Ambuhl
Guest
Posts: n/a
 
      12-07-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> 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
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      12-07-2007
Jack Klein <(E-Mail Removed)> writes:

> On Fri, 07 Dec 2007 03:38:22 +0000, Ben Bacarisse
> <(E-Mail Removed)> wrote in comp.lang.c:

<snip>
>> 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.


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."

--
Ben.
 
Reply With Quote
 
Bryan
Guest
Posts: n/a
 
      12-07-2007
On 7 Dec, 07:17, Martin Ambuhl <(E-Mail Removed)> wrote:

<snip>

> 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 ?

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
(const char *cp) and (char *p) are consistent type, (const char **cpp) and (char **pp) are not consistent lovecreatesbeauty C Programming 1 05-09-2006 08:01 AM
/usr/bin/ld: ../../dist/lib/libjsdombase_s.a(BlockGrouper.o)(.text+0x98): unresolvable relocation against symbol `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostre silverburgh.meryl@gmail.com C++ 3 03-09-2006 12:14 AM
char *fred; char * fred; char *fred; any difference? Ben Pfaff C Programming 5 01-17-2004 07:37 PM
The difference between char a[6] and char *p=new char[6] ? wwj C Programming 24 11-07-2003 05:27 PM
the difference between char a[6] and char *p=new char[6] . wwj C++ 7 11-05-2003 12:59 AM



Advertisments