What is the C++ type conversion precedence?

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

    What is the C++ type conversion precedence?

    Hi,

    Please see the following code and the output. It seems that if one of
    %'s oprand is unsigned, the other will also be converted to unsigned.

    There is a operator precedence table in wikipedia. I'm wondering what
    is the general rule in type conversions.

    Thanks,
    Peng

    #include <iostream>

    int main() {
    std::cout << -10 % 3 << std::endl;
    std::cout << -10 % static_cast<uns igned>(3) << std::endl;
    std::cout << static_cast<uns igned>(-10) % static_cast<uns igned>(3)
    << std::endl;
    std::cout << 10 % 3 << std::endl;
    }

    $./main-g.exe
    -1
    0
    0
    1
  • Peng Yu

    #2
    Re: What is the C++ type conversion precedence?

    On Jul 17, 1:53 pm, "Alf P. Steinbach" <al...@start.no wrote:
    * Peng Yu:
    >
    Hi,
    >
    Please see the following code and the output. It seems that if one of
    %'s oprand is unsigned, the other will also be converted to unsigned.
    >
    Yes. Usual promotion of arguments. In the standard known as the "usual
    arithmetic conversions".
    >
    I tried to write a simplified explanation here but it seems the rules are not
    amenable to simplification.
    >
    But the general idea is an automatic promotion up to some common type that
    ideally should be able to represent all possible values of both arguments.
    In the case of "-10 % static_cast<uns igned>(3)", I would think it is
    as reasonable to convert it to
    "-10 % static_cast<int >(static_cast<u nsigned>(3))" as to
    "static_cast<un signed>(-10) % static_cast<uns igned>(3)".

    But why C++ choose the latter one?
    >
    There is a operator precedence table in wikipedia. I'm wondering what
    is the general rule in type conversions.
    >
    C++ is not based on operator precedence. However as a practical matter one can
    often make do with thinking in terms of operator precedence. In effect, the
    syntax rules are designed from the point of view of achieving operator
    precedence for e.g. boolean, arithmetic and relational operators.

    Comment

    • red floyd

      #3
      Re: What is the C++ type conversion precedence?

      Peng Yu wrote:
      On Jul 17, 1:53 pm, "Alf P. Steinbach" <al...@start.no wrote:
      >* Peng Yu:
      >>
      >>Hi,
      >>Please see the following code and the output. It seems that if one of
      >>%'s oprand is unsigned, the other will also be converted to unsigned.
      >Yes. Usual promotion of arguments. In the standard known as the "usual
      >arithmetic conversions".
      >>
      >I tried to write a simplified explanation here but it seems the rules are not
      >amenable to simplification.
      >>
      >But the general idea is an automatic promotion up to some common type that
      >ideally should be able to represent all possible values of both arguments.
      >
      In the case of "-10 % static_cast<uns igned>(3)", I would think it is
      as reasonable to convert it to
      "-10 % static_cast<int >(static_cast<u nsigned>(3))" as to
      "static_cast<un signed>(-10) % static_cast<uns igned>(3)".
      >
      But why C++ choose the latter one?
      >
      Because that's what the Standard says to do. Probably because that's
      how C did it.

      Comment

      • James Kanze

        #4
        Re: What is the C++ type conversion precedence?

        On Jul 18, 12:24 am, Peng Yu <PengYu...@gmai l.comwrote:
        On Jul 17, 1:53 pm, "Alf P. Steinbach" <al...@start.no wrote:
        In the case of "-10 % static_cast<uns igned>(3)", I would think
        it is as reasonable to convert it to "-10 %
        static_cast<int >(static_cast<u nsigned>(3))" as to
        "static_cast<un signed>(-10) % static_cast<uns igned>(3)".
        Reasonable doesn't count for much here. All that really counts
        is the standard.
        But why C++ choose the latter one?
        Because that's what C did? And C choose the latter because they
        had to choose one. Depending on the application, it is
        sometimes better to preserve sign, and sometimes better to
        preserve value. From my imperfect memory (and thus to be taken
        with a grain of salt): K&R didn't really make it clear which one
        was to be preferred, and early compilers varied (although if
        memory serves me right, Johnson's pcc---the first C compiler to
        "escape" from Bell Labs---preserved value). So no matter what
        the C committee chose, it would break some code. I don't really
        remember any of the arguments, but one thing that does occur to
        me: the conversion of signed to unsigned is always well defined;
        the conversion of unsigned to signed is implementation defined
        (and may result in an implementation defined signal). While in
        your example, it's obvious what the first would mean, try:
        -10 - static_cast< unsigned >( -3 )
        Rewriting it according to your first suggestion results in
        implementation defined behavior (and possibly a signal);
        rewriting it according to the second is well defined (for a
        given size of int).

        The whole thing is a mess, and the basic rule is to use int
        unless there is a very strong reason to do otherwise, and to
        limit unsigned types to cases where you need the modulo
        arithmetic, or are doing bit manipulations (so that >is well
        defined), or are accessing raw memory (as unsigned char). An
        even more important rule, however, is not to mix signed an
        unsigned, so faced with a poorly designed library, which uses
        unsigned types for other things (like the number of elements in
        an array), you should stick with unsigned types when interfacing
        with it. (In sum, a real PITA.)

        --
        James Kanze (GABI Software) email:james.kan ze@gmail.com
        Conseils en informatique orientée objet/
        Beratung in objektorientier ter Datenverarbeitu ng
        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

        Comment

        • Victor Bazarov

          #5
          Re: What is the C++ type conversion precedence?

          Peng Yu wrote:
          Please see the following code and the output. It seems that if one of
          %'s oprand is unsigned, the other will also be converted to unsigned.
          >
          There is a operator precedence table in wikipedia. I'm wondering what
          is the general rule in type conversions.
          Conversions/promotions take place first, then all operations are performed.
          >
          Thanks,
          Peng
          >
          #include <iostream>
          >
          int main() {
          std::cout << -10 % 3 << std::endl;
          std::cout << -10 % static_cast<uns igned>(3) << std::endl;\
          -10 is made unsigned, then % is evalutated. And since the division of
          all the even powers of 2 minus 10 by 3 is exact (no remainder), you get
          your 0 for your size of 'int', which is either 16 or 32 or 64...
          std::cout << static_cast<uns igned>(-10) % static_cast<uns igned>(3)
          << std::endl;
          Same thing here.
          std::cout << 10 % 3 << std::endl;
          }
          >
          $./main-g.exe
          -1
          0
          0
          1
          V
          --
          Please remove capital 'A's when replying by e-mail
          I do not respond to top-posted replies, please don't ask

          Comment

          • Victor Bazarov

            #6
            Re: What is the C++ type conversion precedence?

            Peng Yu wrote:
            [..]
            In the case of "-10 % static_cast<uns igned>(3)", I would think it is
            as reasonable to convert it to
            "-10 % static_cast<int >(static_cast<u nsigned>(3))" as to
            "static_cast<un signed>(-10) % static_cast<uns igned>(3)".
            >
            But why C++ choose the latter one?
            Are you asking why the compiler does that or why the language is
            specified the way it's specified?

            The obvious answer to the former: because the Standard says so (5/9,
            last bullet item). I do not really know the answer to the latter, but
            if I had to guess, the reasons of simplicity would probably win.
            [..]
            V
            --
            Please remove capital 'A's when replying by e-mail
            I do not respond to top-posted replies, please don't ask

            Comment

            Working...