Unsigned/Signed Mismatch

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • MiniDisc_2k2

    Unsigned/Signed Mismatch

    Okay, here's a question about the standard. What does it say about
    unsigned/signed mismatches in a comparison statement:

    char a = 3;
    unsigned char b = 255;
    if (a<b)

    Now what's the real answer here? If a is converted to unsigned, then b>a.
    But, if b is converted to signed,then a>b. What's the correct coversion
    (what is the compiler supposed to do?)

    --
    MiniDisc_2k2
    To reply, replace nospam.com with cox dot net.

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.e du ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

  • Ioannis Vranos

    #2
    Re: Unsigned/Signed Mismatch

    "Victor Bazarov" <v.Abazarov@att Abi.com> wrote in message
    news:vgrkp9r49l l284@corp.super news.com...[color=blue]
    >
    > Integral promotions are applied to both operands here. Both
    > 'a' and 'b' are converted to 'int', if 'int' can represent the
    > values of the source type, or to 'unsigned' otherwise. In
    > a usual scenario where sizeof(int) > 1, both 'a' and 'b' shall
    > become 'int' and then compared. There is no need for the mis-
    > match warning, IMHO. If sizeof(int) == 1, then not all unsigned
    > char values can be represented by 'int'. In such case both 'a'
    > and 'b' will be converted to 'unsigned int'. In that case, if
    > 'a' is negative, you will not get the intended comparison for
    > the unsigned value for a negative 'a' will be formed by copying
    > the bit pattern (whatever that results into). Imagine that if
    > 'a' is -1, and 'b' is 255, and sizeof(int)==1, and you're on
    > a two's complement machine, unsigned(a) will be at least 65535.
    > And you will get (a < b) == false. In this case the warning
    > is warranted, IMHO.[/color]

    ?

    In your hypothetical scenario (sizeof(char)== sizeof(int)) if you have a
    signed char it will be converted to long, not to unsigned int.






    --
    Ioannis

    * Programming pages: http://www.noicys.freeurl.com
    * Alternative URL 1: http://run.to/noicys
    * Alternative URL 2: http://www.noicys.cjb.net

    Comment

    • Ioannis Vranos

      #3
      Re: Unsigned/Signed Mismatch

      ""MiniDisc_2k2" " <MattDelB@nospa m.com> wrote in message
      news:%jjPa.31$z d4.2@lakeread02 ...[color=blue]
      > Okay, here's a question about the standard. What does it say about
      > unsigned/signed mismatches in a comparison statement:
      >
      > char a = 3;
      > unsigned char b = 255;
      > if (a<b)
      >
      > Now what's the real answer here? If a is converted to unsigned, then b>a.
      > But, if b is converted to signed,then a>b. What's the correct coversion
      > (what is the compiler supposed to do?)[/color]


      At first keep in mind that char (differently from other "plain" integer
      types) can be either signed or unsigned. If you want one of the two in
      specific, you have to declare it explicitly (e.g. signed char a=3).


      Assuming you wish your above code to be:


      signed char a = 3;
      unsigned char b = 255;
      if (a<b)


      Both unsigned char and signed char get converted to int during the
      expression evaluation.


      So in summary, a either signed char either unsigned gets converted to int.





      --
      Ioannis

      * Programming pages: http://www.noicys.freeurl.com
      * Alternative URL 1: http://run.to/noicys
      * Alternative URL 2: http://www.noicys.cjb.net

      Comment

      • Ioannis Vranos

        #4
        Re: Unsigned/Signed Mismatch

        "Ron Natalie" <ron@sensor.com > wrote in message
        news:3f0ddae5$0 $87832$9a6e19ea @news.newshosti ng.com...[color=blue]
        >
        > "Ioannis Vranos" <ivr@nothis.ema ils.ru> wrote in message[/color]
        news:3f0dd749$0 $233$4d4eb98e@r ead.news.gr.uu. net...[color=blue]
        >[color=green]
        > >
        > > In your hypothetical scenario (sizeof(char)== sizeof(int)) if you have a
        > > signed char it will be converted to long, not to unsigned int.
        > >[/color]
        > Why would it. The signed char is promoted to int, the unsigned char is
        > promoted to unsigned int (4.5), and then since one is unsigned, the ohter
        > is converted to unsigned. long doesn't ever enter into the discussion.[/color]


        Yes i just checked the standard and you are right. However that would be a
        stupid compiler. The standard allows stupid implementations but i do not
        think such an implementation exists out there.





        --
        Ioannis

        * Programming pages: http://www.noicys.freeurl.com
        * Alternative URL 1: http://run.to/noicys
        * Alternative URL 2: http://www.noicys.cjb.net

        Comment

        • Francis Glassborow

          #5
          Re: Unsigned/Signed Mismatch

          In article <%jjPa.31$zd4.2 @lakeread02>, MiniDisc_2k2
          <MattDelB@nospa m.com> writes[color=blue]
          >Okay, here's a question about the standard. What does it say about
          >unsigned/signed mismatches in a comparison statement:
          >
          >char a = 3;
          >unsigned char b = 255;
          >if (a<b)
          >
          >Now what's the real answer here? If a is converted to unsigned, then b>a.
          >But, if b is converted to signed,then a>b. What's the correct coversion
          >(what is the compiler supposed to do?)[/color]

          No, the normal integral promotions are applied first Which only becomes
          mildly interesting on systems where all integral types are the same
          size.

          ---
          [ comp.std.c++ is moderated. To submit articles, try just posting with ]
          [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.e du ]
          [ --- Please see the FAQ before posting. --- ]
          [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

          Comment

          • MiniDisc_2k2

            #6
            Re: Unsigned/Signed Mismatch


            "Ioannis Vranos" <ivr@nothis.ema ils.ru> wrote in message
            news:3f0dd160$0 $245$4d4eb98e@r ead.news.gr.uu. net...[color=blue]
            > ""MiniDisc_2k2" " <MattDelB@nospa m.com> wrote in message
            > news:%jjPa.31$z d4.2@lakeread02 ...[color=green]
            > > Okay, here's a question about the standard. What does it say about
            > > unsigned/signed mismatches in a comparison statement:
            > >
            > > char a = 3;
            > > unsigned char b = 255;
            > > if (a<b)
            > >
            > > Now what's the real answer here? If a is converted to unsigned, then[/color][/color]
            b>a.[color=blue][color=green]
            > > But, if b is converted to signed,then a>b. What's the correct coversion
            > > (what is the compiler supposed to do?)[/color]
            >
            >
            > At first keep in mind that char (differently from other "plain" integer
            > types) can be either signed or unsigned. If you want one of the two in
            > specific, you have to declare it explicitly (e.g. signed char a=3).
            >
            >
            > Assuming you wish your above code to be:
            >
            >
            > signed char a = 3;
            > unsigned char b = 255;
            > if (a<b)
            >
            >
            > Both unsigned char and signed char get converted to int during the
            > expression evaluation.
            >
            >
            > So in summary, a either signed char either unsigned gets converted to int.
            >
            >[/color]

            Well actually I was using chars only to save my mind from calculating it all
            out. Let's try again.

            I also intended this code to be used on a two's complement machine.

            Use this:

            signed int a = 3;
            unsigned int b = -1; /* thus being the highest number represented by
            unsigned int*/
            if (b<a)

            Now. If b were converted to a signed integer, b<a would be -1<3 == true. If
            a were converted to an unsigned integer, we would get 65535 < 3 == false (in
            16-bit environment). Which representation does it follow. Does it proceed
            like the char conversion, where it is converted to a signed int? Is this at
            all standardized, or does the compiler get to pick?

            --
            MiniDisc_2k2

            ---
            [ comp.std.c++ is moderated. To submit articles, try just posting with ]
            [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.e du ]
            [ --- Please see the FAQ before posting. --- ]
            [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

            Comment

            • Andy Sawyer

              #7
              Re: Unsigned/Signed Mismatch

              In article <%jjPa.31$zd4.2 @lakeread02>,
              on Thu, 10 Jul 2003 20:34:29 +0000 (UTC),
              MattDelB@nospam .com ("MiniDisc_2k2" ) wrote:
              [color=blue]
              > Okay, here's a question about the standard. What does it say about
              > unsigned/signed mismatches in a comparison statement:
              >
              > char a = 3;
              > unsigned char b = 255;
              > if (a<b)
              >
              > Now what's the real answer here? If a is converted to unsigned, then b>a.
              > But, if b is converted to signed,then a>b
              >
              > What's the correct coversion
              > (what is the compiler supposed to do?)[/color]

              5.9p2 tells us that the usual arithmetic conversions (5p9) are performed.

              4.5p1 tells us that 'a' is promoted to signed int,

              It also tells us that b is promoted to either signed int or unsigned
              int, depending on the implementation, specifically:

              ,----
              | An rvalue of type char, signed char, unsigned char, short int, or
              | unsigned short int can be converted to an rvalue of type int if int
              | can represent all the values of the source type; otherwise, the source
              | rvalue can be converted to an rvalue of type unsigned int.
              `----

              Either way, it will still have the value 255 (I assume from your magic
              number of 255, you're thinking of a platform with 8-bit characters and
              you're concerned about sign-extention? Not a problem here :)

              If b has been promoted to signed int (such as in an 8-bit char
              environment), then the comparison is performed with signed integers, so
              (a<b) yields true.

              If b has been promoted to unsigned int, a is then also converted to
              unsigned int (5p9) and the comparison is performed using unsigned
              integers, and again (a<b) yields true.

              In this last case (b promoted to unsigned, a converted to unsigned),
              then the result is highly dependant on the actual value of a, as 4.7p3
              says:

              ,----
              | If the destination type is signed, the value is unchanged if it can be
              | represented in the destination type (and bitfield width); otherwise,
              | the value is implementation-defined.
              `----

              Since, in your example, a == 3, then it can comfortable fit inside an
              unsigned int and hence is unchanged.

              At least, that's the way _I_ read the standard :)

              Regards,
              Andy S.
              --
              "Light thinks it travels faster than anything but it is wrong. No matter
              how fast light travels it finds the darkness has always got there first,
              and is waiting for it." -- Terry Pratchett, Reaper Man

              ---
              [ comp.std.c++ is moderated. To submit articles, try just posting with ]
              [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.e du ]
              [ --- Please see the FAQ before posting. --- ]
              [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

              Comment

              • Andy Sawyer

                #8
                Re: Unsigned/Signed Mismatch

                In article <3nmPa.50$zd4.4 2@lakeread02>,
                on Thu, 10 Jul 2003 23:10:49 +0000 (UTC),
                MattDelB@nospam .com ("MiniDisc_2k2" ) wrote:
                [color=blue]
                > Well actually I was using chars only to save my mind from calculating it all
                > out. Let's try again.
                >
                > I also intended this code to be used on a two's complement machine.
                >
                > Use this:
                >
                > signed int a = 3;
                > unsigned int b = -1; /* thus being the highest number represented by
                > unsigned int*/[/color]

                No, it's a signed integer converted to an unsigned integer. And it's a
                value that the unsigned target cannot represent, so the value of b is
                actually implementation-defined.
                If you *actually* want the highest value represented by an unsigned
                integer, then write::

                unsinged int b = std::numeric_li mits<unsigned int>::max();
                [color=blue]
                > if (b<a)
                >
                > Now. If b were converted to a signed integer[/color]

                Which it won't be.
                [color=blue]
                > b<a would be -1<3 == true. If
                > a were converted to an unsigned integer[/color]

                It will be.
                [color=blue]
                > we would get 65535 < 3 == false (in
                > 16-bit environment). Which representation does it follow. Does it proceed
                > like the char conversion, where it is converted to a signed int? Is this at
                > all standardized, or does the compiler get to pick?[/color]

                It's standardized in detail, see:

                4.5 Integral Promotions
                4.7 Integral Conversions
                5p9 "the usual suspects^H^H^H^ H^H^H^H^H arithmetic conversions":)

                What the compiler *can* pick is the result of the conversion from signed
                to unigned types if the value of the signed type cannot be represented
                in the unsigned type (see 4.7p3)

                Regards,
                Andy S
                --
                "Light thinks it travels faster than anything but it is wrong. No matter
                how fast light travels it finds the darkness has always got there first,
                and is waiting for it." -- Terry Pratchett, Reaper Man

                ---
                [ comp.std.c++ is moderated. To submit articles, try just posting with ]
                [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.e du ]
                [ --- Please see the FAQ before posting. --- ]
                [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

                Comment

                • Ben Hutchings

                  #9
                  Re: Unsigned/Signed Mismatch

                  In article <3f0e36ac$0$243 $4d4eb98e@read. news.gr.uu.net> ,
                  "Ioannis Vranos" wrote:
                  <snip>[color=blue]
                  > The C++ standard says:
                  >
                  > [conv.prom] 4.5 Integral promotions
                  > 1 An rvalue of type char, signed char, unsigned char, short int, or
                  > unsigned short int can be converted to an rvalue of type int if int can
                  > represent all the values of the source type; otherwise, the source
                  > rvalue can be converted to an rvalue of type unsigned int.[/color]
                  <snip>[color=blue]
                  > The (1) is your case.[/color]
                  <snip>

                  No. Do you see "signed int" in that list?

                  Comment

                  • Andy Sawyer

                    #10
                    Re: Unsigned/Signed Mismatch

                    In article <3f0dd160$0$245 $4d4eb98e@read. news.gr.uu.net> ,
                    on Thu, 10 Jul 2003 21:55:32 +0000 (UTC),
                    ivr@nothis.emai ls.ru (Ioannis Vranos) wrote:
                    [color=blue]
                    > ""MiniDisc_2k2" " <MattDelB@nospa m.com> wrote in message
                    > news:%jjPa.31$z d4.2@lakeread02 ...[color=green]
                    > > Okay, here's a question about the standard. What does it say about
                    > > unsigned/signed mismatches in a comparison statement:
                    > >
                    > > char a = 3;
                    > > unsigned char b = 255;
                    > > if (a<b)
                    > >
                    > > Now what's the real answer here? If a is converted to unsigned, then b>a.
                    > > But, if b is converted to signed,then a>b. What's the correct coversion
                    > > (what is the compiler supposed to do?)[/color]
                    >
                    >
                    > At first keep in mind that char (differently from other "plain" integer
                    > types) can be either signed or unsigned. If you want one of the two in
                    > specific, you have to declare it explicitly (e.g. signed char a=3).[/color]

                    Remember that char, signed char and unsigned char are three disticnt
                    types. FWIW, if I'm using the value in an arithmetic context, then I
                    always write either signed char or unsigned char. If I'm using it to
                    represent text elements, then I write char. And I probably wouldn't
                    write:

                    char a = 3;

                    I'd write

                    char a = '\003';

                    or, more likely - given my current project:

                    char a = ASCII::ETX;
                    [color=blue]
                    > Assuming you wish your above code to be:
                    >
                    > signed char a = 3;
                    > unsigned char b = 255;
                    > if (a<b)[/color]

                    I suspect if he'd wished that, he'd have written that.
                    [color=blue]
                    > Both unsigned char and signed char get converted to int during the
                    > expression evaluation.[/color]

                    In fact, unsigned char may be promoted to unsigned int (depending on the
                    environment).
                    [color=blue]
                    > So in summary, a either signed char either unsigned gets converted to
                    > int.[/color]

                    I had trouble parsing that - I assume you meant

                    "So in summary, either a signed char or unsigned char gets converted to
                    int."
                    ?

                    If that is what you meant, then it isn't strictly true on all
                    platforms. Please see my other post for why :)

                    Regards,
                    Andy S.
                    --
                    "Light thinks it travels faster than anything but it is wrong. No matter
                    how fast light travels it finds the darkness has always got there first,
                    and is waiting for it." -- Terry Pratchett, Reaper Man

                    ---
                    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
                    [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.e du ]
                    [ --- Please see the FAQ before posting. --- ]
                    [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

                    Comment

                    • Ioannis Vranos

                      #11
                      Re: Unsigned/Signed Mismatch

                      "Jack Klein" <jackklein@spam cop.net> wrote in message
                      news:7rvrgv8jv2 r1425q8496cca08 g1d4gl8o2@4ax.c om...[color=blue][color=green]
                      > >
                      > > Yes i just checked the standard and you are right. However that would be[/color][/color]
                      a[color=blue][color=green]
                      > > stupid compiler. The standard allows stupid implementations but i do not
                      > > think such an implementation exists out there.[/color]
                      >
                      > No, that would be a conforming compiler. One that did anything else
                      > in this case would be the stupid one, because it would be
                      > non-conforming.[/color]


                      Let me clarify what i mean, a compiler where sizeof(int)==1 would be a
                      conforming, stupid compiler.






                      --
                      Ioannis

                      * Programming pages: http://www.noicys.freeurl.com
                      * Alternative URL 1: http://run.to/noicys
                      * Alternative URL 2: http://www.noicys.cjb.net

                      Comment

                      • Victor Bazarov

                        #12
                        Re: Unsigned/Signed Mismatch

                        "Ioannis Vranos" <ivr@nothis.ema ils.ru> wrote...[color=blue]
                        > "Jack Klein" <jackklein@spam cop.net> wrote in message
                        > news:7rvrgv8jv2 r1425q8496cca08 g1d4gl8o2@4ax.c om...[color=green][color=darkred]
                        > > >
                        > > > Yes i just checked the standard and you are right. However that would[/color][/color][/color]
                        be[color=blue]
                        > a[color=green][color=darkred]
                        > > > stupid compiler. The standard allows stupid implementations but i do[/color][/color][/color]
                        not[color=blue][color=green][color=darkred]
                        > > > think such an implementation exists out there.[/color]
                        > >
                        > > No, that would be a conforming compiler. One that did anything else
                        > > in this case would be the stupid one, because it would be
                        > > non-conforming.[/color]
                        >
                        >
                        > Let me clarify what i mean, a compiler where sizeof(int)==1 would be a
                        > conforming, stupid compiler.[/color]

                        Imagine how the creators of the compilers for many different
                        Digital Signal Processors feel when they read your opinion
                        of their compiler. Yes, on many DSPs sizeof(long) ==
                        sizeof(int) == sizeof(short) == 1. Their byte has 32 bits
                        in it.

                        If you haven't worked with something, it doesn't mean that
                        it's "stupid"...


                        Comment

                        • William M. Miller

                          #13
                          Re: Unsigned/Signed Mismatch

                          "Andy Sawyer" <andys@despamme d.com> wrote in message
                          news:llv6szff.f sf@evo6.com...[color=blue]
                          > In article <3nmPa.50$zd4.4 2@lakeread02>,
                          > on Thu, 10 Jul 2003 23:10:49 +0000 (UTC),
                          > MattDelB@nospam .com ("MiniDisc_2k2" ) wrote:
                          >[color=green]
                          > > signed int a = 3;
                          > > unsigned int b = -1; /* thus being the highest number represented by
                          > > unsigned int*/[/color]
                          >
                          > No, it's a signed integer converted to an unsigned integer. And it's a
                          > value that the unsigned target cannot represent, so the value of b is
                          > actually implementation-defined.[/color]
                          ....[color=blue]
                          > What the compiler *can* pick is the result of the conversion from signed
                          > to unigned types if the value of the signed type cannot be represented
                          > in the unsigned type (see 4.7p3)[/color]

                          Wrong paragraph. 4.7p3 deals with conversion to signed types
                          ("if the destination type is signed..."), and the result is
                          implementation-defined, as you say. The description of
                          conversion to an unsigned type is in 4.7p2, and the result is
                          defined by the Standard, not by the implementation:

                          If the designation type is unsigned, the resulting value is
                          the least unsigned integer congruent to the source integer
                          (modulo 2**n where n is the number of bits used to represent
                          the unsigned type). [Note: In a two's complement
                          representation, this conversion is conceptual and there is
                          no change in the bit pattern (if there is no truncation). ]

                          -- William M. Miller


                          ---
                          [ comp.std.c++ is moderated. To submit articles, try just posting with ]
                          [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.e du ]
                          [ --- Please see the FAQ before posting. --- ]
                          [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

                          Comment

                          • Ron Natalie

                            #14
                            Re: Unsigned/Signed Mismatch


                            ""MiniDisc_2k2" " <MattDelB@nospa m.com> wrote in message news:%jjPa.31$z d4.2@lakeread02 ...[color=blue]
                            > Okay, here's a question about the standard. What does it say about
                            > unsigned/signed mismatches in a comparison statement:
                            >
                            > char a = 3;
                            > unsigned char b = 255;
                            > if (a<b)
                            >
                            > Now what's the real answer here? If a is converted to unsigned, then b>a.
                            > But, if b is converted to signed,then a>b. What's the correct coversion
                            > (what is the compiler supposed to do?)
                            >[/color]

                            The usual aritmentic conersions are performd (5.1/9) which means the
                            integral promotions (4.5) are performed which means both a and b are
                            converted to int values of 3 and 255 respectively. The value of a<b
                            therefore is true.


                            ---
                            [ comp.std.c++ is moderated. To submit articles, try just posting with ]
                            [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.e du ]
                            [ --- Please see the FAQ before posting. --- ]
                            [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

                            Comment

                            • Ben Hutchings

                              #15
                              Re: Unsigned/Signed Mismatch

                              In article <llv6szff.fsf@e vo6.com>, Andy Sawyer wrote:[color=blue]
                              > In article <3nmPa.50$zd4.4 2@lakeread02>,
                              > on Thu, 10 Jul 2003 23:10:49 +0000 (UTC),
                              > MattDelB@nospam .com ("MiniDisc_2k2" ) wrote:
                              >[color=green]
                              >> Well actually I was using chars only to save my mind from calculating it
                              >> all out. Let's try again.
                              >>
                              >> I also intended this code to be used on a two's complement machine.
                              >>
                              >> Use this:
                              >>
                              >> signed int a = 3;
                              >> unsigned int b = -1; /* thus being the highest number represented by
                              >> unsigned int*/[/color]
                              >
                              > No, it's a signed integer converted to an unsigned integer. And it's a
                              > value that the unsigned target cannot represent, so the value of b is
                              > actually implementation-defined.[/color]
                              <snip>

                              No, this is well-defined (standard 4.7p2). It's the reverse that is
                              implementation-defined.

                              ---
                              [ comp.std.c++ is moderated. To submit articles, try just posting with ]
                              [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.e du ]
                              [ --- Please see the FAQ before posting. --- ]
                              [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

                              Comment

                              Working...