Supressing sign extension

Discussion in 'C++' started by Dave, Oct 9, 2004.

  1. Dave

    Dave Guest

    I'm working on a program that will be parsing a protocol. My basic storage
    element type is an array of characters or char*. The reason I am using
    char* is because many of the socket and stream functions I'll be using take
    char* as a parameter.

    What I am seeing with my program is that when bit 7 is true, my integers are
    being sign extended. Below is a program that should demonstrate my
    problem. I am encountering this problem in a checksum loop that is adding
    unsigned bytes together. As soon as bit7 is set my numbers become huge
    because something is sign extending the high-byte. I think this may be a
    processor related issue, but how can I overcome it.

    I th

    =============== Example
    #include <iostream>

    int main () {
    // Define some constants
    char ch[10] = { 0x01, 0x05, 0x07, 0x08, 0xFF,
    0x0E, 0x0F, 0x10, 0x17, 0x18 };

    // Observe sign extension
    for (int i=0; i < 10; i++) {
    std::cout << std::dec << "The value of ch[" << i << "] is "
    << std::hex << static_cast<unsigned short>(ch)
    << std::endl;
    }
    return 0;
    }

    ============= a.out
    The value of ch[0] is 1
    The value of ch[1] is 5
    The value of ch[2] is 7
    The value of ch[3] is 8
    The value of ch[4] is ffff
    The value of ch[5] is e
    The value of ch[6] is f
    The value of ch[7] is 10
    The value of ch[8] is 17
    The value of ch[9] is 18
    Dave, Oct 9, 2004
    #1
    1. Advertising

  2. Dave wrote:
    > I'm working on a program that will be parsing a protocol. My basic storage
    > element type is an array of characters or char*. The reason I am using
    > char* is because many of the socket and stream functions I'll be using take
    > char* as a parameter.
    >
    > What I am seeing with my program is that when bit 7 is true, my integers are
    > being sign extended. Below is a program that should demonstrate my
    > problem. I am encountering this problem in a checksum loop that is adding
    > unsigned bytes together. As soon as bit7 is set my numbers become huge
    > because something is sign extending the high-byte. I think this may be a
    > processor related issue, but how can I overcome it.
    >
    > I th
    >
    > =============== Example
    > #include <iostream>
    >
    > int main () {
    > // Define some constants
    > char ch[10] = { 0x01, 0x05, 0x07, 0x08, 0xFF,
    > 0x0E, 0x0F, 0x10, 0x17, 0x18 };
    >
    > // Observe sign extension
    > for (int i=0; i < 10; i++) {
    > std::cout << std::dec << "The value of ch[" << i << "] is "
    > << std::hex << static_cast<unsigned short>(ch)


    probably not portable in 1's complement:

    << std::hex << (reinterpret_cast<unsigned char *>(ch))

    or perhaps better :

    << std::hex << static_cast<unsigned char>(ch)



    > << std::endl;
    > }
    > return 0;
    > }
    >
    > ============= a.out
    > The value of ch[0] is 1
    > The value of ch[1] is 5
    > The value of ch[2] is 7
    > The value of ch[3] is 8
    > The value of ch[4] is ffff
    > The value of ch[5] is e
    > The value of ch[6] is f
    > The value of ch[7] is 10
    > The value of ch[8] is 17
    > The value of ch[9] is 18
    >
    >
    >
    Gianni Mariani, Oct 9, 2004
    #2
    1. Advertising

  3. * Dave:
    > I'm working on a program that will be parsing a protocol. My basic storage
    > element type is an array of characters or char*. The reason I am using
    > char* is because many of the socket and stream functions I'll be using take
    > char* as a parameter.
    >
    > What I am seeing with my program is that when bit 7 is true, my integers are
    > being sign extended. Below is a program that should demonstrate my
    > problem. I am encountering this problem in a checksum loop that is adding
    > unsigned bytes together. As soon as bit7 is set my numbers become huge
    > because something is sign extending the high-byte. I think this may be a
    > processor related issue, but how can I overcome it.
    >
    > I th
    >
    > =============== Example
    > #include <iostream>
    >
    > int main () {
    > // Define some constants
    > char ch[10] = { 0x01, 0x05, 0x07, 0x08, 0xFF,
    > 0x0E, 0x0F, 0x10, 0x17, 0x18 };
    >
    > // Observe sign extension
    > for (int i=0; i < 10; i++) {
    > std::cout << std::dec << "The value of ch[" << i << "] is "
    > << std::hex << static_cast<unsigned short>(ch)


    Here you should either cast to a signed integer type such as 'int'
    (which may produce apparently negative values, but values which can be
    safely casted back to 'char' or 'unsigned char' or 'signed char'), or
    you should use 'unsigned char' in the first place, or you should first
    cast to 'unsigned char'.


    > << std::endl;
    > }
    > return 0;
    > }


    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 9, 2004
    #3
  4. Dave

    Dave Guest

    I managed to solve the problem in a way similar to this:

    int main () {
    char ch[10] = { 0x01, 0x05, 0x07, 0x08, 0xFF,
    0xFE, 0x0F, 0x7F, 0x80, 0x18 };
    unsigned char* puc;
    // Pretend the char* is really an unsigned char*
    puc = reinterpret_cast<unsigned char*>(ch);

    // Casting from a uchar to uint doesn't sign extend.
    for (int i=0; i < 10; i++) {
    std::cout << std::dec << "The value of puc[" << i << "] is "
    << std::hex << static_cast<unsigned int>(puc)
    << std::endl;
    return 0;
    }

    but it seems highly non-portable - comments?.

    The most portable way I can think of would be to manually calculate the
    checksum in two character array. The problem I am working on is summing up
    the bytes of a char* string to create a two byte checksum. But at present,
    sign extension is messing things up.

    If I use the 2 char array approach I could tackle the problem much like an
    assembly language problem. I would look for a carry and increment the high
    byte of the check sum. But the problem then becomes detecting the carry.
    In assembly it is easy...just look for the 'C' flag to change. But how can
    I do that in C++ efficiently. I don't know of any portable interface into
    the processor registers. Is there a guru's trick using shifts or basic
    logic operations?
    Dave, Oct 10, 2004
    #4
  5. * Dave:
    >
    > I managed to solve the problem in a way similar to this:
    >
    > int main () {
    > char ch[10] = { 0x01, 0x05, 0x07, 0x08, 0xFF,
    > 0xFE, 0x0F, 0x7F, 0x80, 0x18 };
    > unsigned char* puc;
    > // Pretend the char* is really an unsigned char*
    > puc = reinterpret_cast<unsigned char*>(ch);


    The need for reinterpret_cast (or a C cast) should be a a very large,
    waving, flashing and noisily flapping red flag telling you that this
    approach is UnGood (TM).



    > // Casting from a uchar to uint doesn't sign extend.
    > for (int i=0; i < 10; i++) {
    > std::cout << std::dec << "The value of puc[" << i << "] is "
    > << std::hex << static_cast<unsigned int>(puc)
    > << std::endl;
    > return 0;
    > }
    >
    > but it seems highly non-portable - comments?.


    I pointed out three better solutions in a previous posting.


    > The most portable way I can think of would be to manually calculate the
    > checksum in two character array. The problem I am working on is summing up
    > the bytes of a char* string to create a two byte checksum. But at present,
    > sign extension is messing things up.


    Post code.


    > If I use the 2 char array approach I could tackle the problem much like an
    > assembly language problem. I would look for a carry and increment the high
    > byte of the check sum. But the problem then becomes detecting the carry.
    > In assembly it is easy...just look for the 'C' flag to change. But how can
    > I do that in C++ efficiently. I don't know of any portable interface into
    > the processor registers. Is there a guru's trick using shifts or basic
    > logic operations?


    Gurus are not telepaths -- you should first describe what you're trying
    to achieve (a bit of code would help).

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 10, 2004
    #5
    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. Herb Stull

    Supressing Menu and Toolbars on Webpage

    Herb Stull, Feb 25, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    498
    Eric Lawrence [MSFT]
    Feb 25, 2004
  2. Michael B Allen

    Supressing Unused Parameter Warnings

    Michael B Allen, May 7, 2004, in forum: C Programming
    Replies:
    11
    Views:
    1,017
    CBFalconer
    May 8, 2004
  3. Jp Calderone

    Supressing PyChecker warnings

    Jp Calderone, Jan 16, 2004, in forum: Python
    Replies:
    1
    Views:
    470
    Rene Pijlman
    Jan 16, 2004
  4. Mark Harrison

    supressing warning message?

    Mark Harrison, Jul 29, 2004, in forum: Python
    Replies:
    2
    Views:
    447
    Mark Harrison
    Jul 29, 2004
  5. SunX

    supressing '\n' at the end

    SunX, Nov 6, 2004, in forum: Python
    Replies:
    2
    Views:
    299
    George Yoshida
    Nov 6, 2004
Loading...

Share This Page