Could someone please explain?!

Discussion in 'C++' started by jignasuk@gmail.com, Jan 6, 2006.

  1. Guest

    Hello,

    1 unsigned char ar[] = "AB";
    2 unsigned int i = 0;
    3 i = *(unsigned int *)ar;

    How does it convert to unsigned int from unsigned char()? After
    executing this three line I am getting 16961! How does this value
    actually derived?

    Thanks
    JK
     
    , Jan 6, 2006
    #1
    1. Advertising

  2. > 1 unsigned char ar[] = "AB";
    > 2 unsigned int i = 0;
    > 3 i = *(unsigned int *)ar;
    >
    > How does it convert to unsigned int from unsigned char()? After
    > executing this three line I am getting 16961! How does this value
    > actually derived?


    ar is the array containing "AB" with a trailing zero to terminate the
    string.
    It is first implicit converted to a pointer to the first character.
    Then you typecast this pointer to a pointer which points to an unsigned int.
    This means that the int starts at the same address as your string. If we
    assume that in your implementation a char is 1 byte and an int is 4 bytes,
    then the int will consists of the A, the B, the trailing zero and the byte
    following that (which can have any value).
    Depending upon your processor this is either with the most significant byte
    at the first or last address.
    An Intel processor will have it at the last address, so i will become
    'A'+'B'*256+0*256*256+unspecified*256*256*256.
    In ASCII 'A' is 65 and 'B' is 66 and apparently the unspecified value was
    zero in this case, so you end up with 65+66*256=16961

    Niels Dybdahl
     
    Niels Dybdahl, Jan 6, 2006
    #2
    1. Advertising

  3. wrote:
    > Hello,
    >
    > 1 unsigned char ar[] = "AB";
    > 2 unsigned int i = 0;
    > 3 i = *(unsigned int *)ar;
    >
    > How does it convert to unsigned int from unsigned char()? After
    > executing this three line I am getting 16961! How does this value
    > actually derived?


    As an aside from Neil's explanation -

    Note that almost everything is implementation and architechture
    dependent here, and not in the domain of std c++.
    1. Size of char, int
    2. Endianness of machine
    3. casting from unsigned char* to int*

    note that this type of typecasting has implementation defined effects
    and hence is almost always guaranteed to be non-portable. Also, avoid
    C-style casts. Use reinterpret_cast in this case (and C++ style casts
    in general).
     
    Neelesh Bodas, Jan 6, 2006
    #3
  4. Bo Persson Guest

    <> skrev i meddelandet
    news:...
    > Hello,
    >
    > 1 unsigned char ar[] = "AB";
    > 2 unsigned int i = 0;
    > 3 i = *(unsigned int *)ar;
    >
    > How does it convert to unsigned int from unsigned char()? After
    > executing this three line I am getting 16961! How does this value
    > actually derived?
    >
    > Thanks
    > JK
    >


    Here's another view of what is happening here:

    The name ar denotes an array of unsigned char. In some places, ar will
    'decay' into a pointer to the first element of the array. Here the
    type of the pointer would be 'unsigned char *'.

    When you cast that pointer to another type, the compiler doesn't
    convert it. It is YOU who say "the pointer is not a pointer to an
    unsigned char, it is really a pointer to an unsigned int. Trust me, I
    know what I am doing!". And the compiler is forced to trust you,
    because that's the contract it works under.

    If you then dereference the pointer, and it actually DOES point to an
    unsigned int, you get the value of the int.

    If you dereference the pointer, and it actually does NOT point to an
    unsigned int, you have broken the contract with the compiler. It is
    the free do do anything it feels like, perhaps show the value 16961.
    Or crash, or format your harddisk. :)


    Just don't lie to the compiler.


    Bo Persson
     
    Bo Persson, Jan 10, 2006
    #4
  5. Tom Wilson Guest

    16961 in Hex is 0x4241

    If you look in a ascii chart, "A" is 0x41 "B" is 0x42.

    Assuming you have a 4-byte unsigned int, the other 2 bytes were 0 at the
    time, though don't count on it.

    -Tom

    "Bo Persson" <> wrote in message
    news:...
    >
    > <> skrev i meddelandet
    > news:...
    >> Hello,
    >>
    >> 1 unsigned char ar[] = "AB";
    >> 2 unsigned int i = 0;
    >> 3 i = *(unsigned int *)ar;
    >>
    >> How does it convert to unsigned int from unsigned char()? After
    >> executing this three line I am getting 16961! How does this value
    >> actually derived?
    >>
    >> Thanks
    >> JK
    >>

    >
    > Here's another view of what is happening here:
    >
    > The name ar denotes an array of unsigned char. In some places, ar will
    > 'decay' into a pointer to the first element of the array. Here the type of
    > the pointer would be 'unsigned char *'.
    >
    > When you cast that pointer to another type, the compiler doesn't convert
    > it. It is YOU who say "the pointer is not a pointer to an unsigned char,
    > it is really a pointer to an unsigned int. Trust me, I know what I am
    > doing!". And the compiler is forced to trust you, because that's the
    > contract it works under.
    >
    > If you then dereference the pointer, and it actually DOES point to an
    > unsigned int, you get the value of the int.
    >
    > If you dereference the pointer, and it actually does NOT point to an
    > unsigned int, you have broken the contract with the compiler. It is the
    > free do do anything it feels like, perhaps show the value 16961. Or crash,
    > or format your harddisk. :)
    >
    >
    > Just don't lie to the compiler.
    >
    >
    > Bo Persson
    >
    >
     
    Tom Wilson, Jan 10, 2006
    #5
  6. Bo Persson Guest

    "Tom Wilson" <> skrev i meddelandet
    news:dq15cb$lfa$...
    > 16961 in Hex is 0x4241
    >
    > If you look in a ascii chart, "A" is 0x41 "B" is 0x42.


    Sure, that's an explanation for why this particular value might show
    up.

    > Assuming you have a 4-byte unsigned int, the other 2 bytes were 0
    > at the time, though don't count on it.


    The problem here is that formally we don't have any unsigned ints in
    sight, just some unsigned chars. Then we tell the compiler that we
    know better, that 'ar' really points to an unsigned char anyway.
    "Honest, Gov. You can trust me. I would never lie to anyone!".

    And we don't really have 4 bytes (if that is the size of an unsigned
    int on this particular machine), we just have 3. So now we try to look
    at the presumably first 4 bytes out of these 3. What happens? Poof?
    16961? Something else?

    Who knows, we have broken the contract. The compiler has the right to
    sue us!


    Bo Persson



    >
    > -Tom
    >
    > "Bo Persson" <> wrote in message
    > news:...
    >>
    >> <> skrev i meddelandet
    >> news:...
    >>> Hello,
    >>>
    >>> 1 unsigned char ar[] = "AB";
    >>> 2 unsigned int i = 0;
    >>> 3 i = *(unsigned int *)ar;
    >>>
    >>> How does it convert to unsigned int from unsigned char()? After
    >>> executing this three line I am getting 16961! How does this value
    >>> actually derived?
    >>>
    >>> Thanks
    >>> JK
    >>>

    >>
    >> Here's another view of what is happening here:
    >>
    >> The name ar denotes an array of unsigned char. In some places, ar
    >> will 'decay' into a pointer to the first element of the array. Here
    >> the type of the pointer would be 'unsigned char *'.
    >>
    >> When you cast that pointer to another type, the compiler doesn't
    >> convert it. It is YOU who say "the pointer is not a pointer to an
    >> unsigned char, it is really a pointer to an unsigned int. Trust me,
    >> I know what I am doing!". And the compiler is forced to trust you,
    >> because that's the contract it works under.
    >>
    >> If you then dereference the pointer, and it actually DOES point to
    >> an unsigned int, you get the value of the int.
    >>
    >> If you dereference the pointer, and it actually does NOT point to
    >> an unsigned int, you have broken the contract with the compiler. It
    >> is the free do do anything it feels like, perhaps show the value
    >> 16961. Or crash, or format your harddisk. :)
    >>
    >>
    >> Just don't lie to the compiler.
    >>
    >>
    >> Bo Persson
    >>
    >>

    >
    >
     
    Bo Persson, Jan 10, 2006
    #6
    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. Gactimus
    Replies:
    22
    Views:
    729
    jeffc
    Dec 15, 2004
  2. Alexander Mahone

    Could someone please explain me this error?

    Alexander Mahone, May 2, 2008, in forum: C Programming
    Replies:
    5
    Views:
    271
    Igmar Palsenberg
    May 5, 2008
  3. wkevin
    Replies:
    4
    Views:
    582
    Edward A. Falk
    Nov 7, 2011
  4. Rubyist
    Replies:
    1
    Views:
    103
    Ross Bamford
    Feb 2, 2006
  5. John Small
    Replies:
    4
    Views:
    108
    John Small
    Feb 2, 2009
Loading...

Share This Page