char change to int, so weird.

Discussion in 'C Programming' started by zhangsonglovexiaoniuniu@gmail.com, Dec 7, 2007.

  1. Guest

    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
    , Dec 7, 2007
    #1
    1. Advertising

  2. ""
    <> 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.
    Ben Bacarisse, Dec 7, 2007
    #2
    1. Advertising

  3. Guest

    On 12ÔÂ7ÈÕ, ÉÏÎç11ʱ38·Ö, Ben Bacarisse <> wrote:
    > ""
    >
    > <> 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?
    , Dec 7, 2007
    #3
  4. Jack Klein Guest

    On Fri, 07 Dec 2007 03:38:22 +0000, Ben Bacarisse
    <> wrote in comp.lang.c:

    > ""
    > <> 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
    Jack Klein, Dec 7, 2007
    #4
  5. 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
    Martin Ambuhl, Dec 7, 2007
    #5
  6. Jack Klein <> writes:

    > On Fri, 07 Dec 2007 03:38:22 +0000, Ben Bacarisse
    > <> 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.
    Ben Bacarisse, Dec 7, 2007
    #6
  7. Bryan Guest

    On 7 Dec, 07:17, Martin Ambuhl <> 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 ?
    Bryan, Dec 7, 2007
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Schnoffos
    Replies:
    2
    Views:
    1,209
    Martien Verbruggen
    Jun 27, 2003
  2. trey

    newbie: char* int and char *int

    trey, Sep 10, 2003, in forum: C Programming
    Replies:
    7
    Views:
    403
    Irrwahn Grausewitz
    Sep 10, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,629
    Old Wolf
    Jan 20, 2004
  4. lovecreatesbeauty
    Replies:
    1
    Views:
    1,043
    Ian Collins
    May 9, 2006
  5. gert
    Replies:
    20
    Views:
    1,158
Loading...

Share This Page