Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Type Promotion in C

Type Promotion in C

Scheduled Pinned Locked Moved C / C++ / MFC
question
13 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • _ Offline
    _ Offline
    __yash__
    wrote on last edited by
    #1

    unsigned long i; //4-bytes, int: 4-bytes
    short s; //2-bytes
    signed char c; //1-byte

    i = (s<<15) + (c <<9);

    How will type conversion take place in this case? Is it that: 1. s will remain short(2 bytes) thus shifting the LSB into the MSB and remaining bits turn 0; c is promoted to short then left-shift 9 performed. The final R-value is promoted to unsigned long and saved into i. or 2. s and c both get converted to unsigned long before performing the shift operation (thus we do not lose any of the left-shifted bits) or something else happens. I tried it in VS6.0 and the result seem to indicate that in both s and c I did not lose any bit upon left-shifting as if s and c acted as if they were a 4-byte data type (long or int)

    _ A 2 Replies Last reply
    0
    • _ __yash__

      unsigned long i; //4-bytes, int: 4-bytes
      short s; //2-bytes
      signed char c; //1-byte

      i = (s<<15) + (c <<9);

      How will type conversion take place in this case? Is it that: 1. s will remain short(2 bytes) thus shifting the LSB into the MSB and remaining bits turn 0; c is promoted to short then left-shift 9 performed. The final R-value is promoted to unsigned long and saved into i. or 2. s and c both get converted to unsigned long before performing the shift operation (thus we do not lose any of the left-shifted bits) or something else happens. I tried it in VS6.0 and the result seem to indicate that in both s and c I did not lose any bit upon left-shifting as if s and c acted as if they were a 4-byte data type (long or int)

      _ Offline
      _ Offline
      _Superman_
      wrote on last edited by
      #2

      All shifts take place in a register. The registers are 32-bit in a 32-bit OS. So even though the shift overflows the variable, it will still remain in the register. That's the reason you don't loose any bits.

      «_Superman_» I love work. It gives me something to do between weekends.
      Microsoft MVP (Visual C++)

      _ 1 Reply Last reply
      0
      • _ _Superman_

        All shifts take place in a register. The registers are 32-bit in a 32-bit OS. So even though the shift overflows the variable, it will still remain in the register. That's the reason you don't loose any bits.

        «_Superman_» I love work. It gives me something to do between weekends.
        Microsoft MVP (Visual C++)

        _ Offline
        _ Offline
        __yash__
        wrote on last edited by
        #3

        I understand that the shifts take place in registers but then the evaluated values have to be stored back into their respective variables, which are of type short and char, which cannot hold 4-byte values.

        C _ 2 Replies Last reply
        0
        • _ __yash__

          I understand that the shifts take place in registers but then the evaluated values have to be stored back into their respective variables, which are of type short and char, which cannot hold 4-byte values.

          C Offline
          C Offline
          CPallini
          wrote on last edited by
          #4

          Ralph_2 wrote:

          but then the evaluated values have to be stored back into their respective variables

          Nope. Why do you think that?

          If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
          This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
          [My articles]

          _ 2 Replies Last reply
          0
          • C CPallini

            Ralph_2 wrote:

            but then the evaluated values have to be stored back into their respective variables

            Nope. Why do you think that?

            If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
            This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
            [My articles]

            _ Offline
            _ Offline
            __yash__
            wrote on last edited by
            #5

            If I have a char variable and I perform left-shift 4 times I lose the 4 MSB bits For instance,

            unsigned char c = 4;
            c= c<<2; // Now c is 16 (10000)b
            c= c<<4; // Now c becomes 0 and not 64 (100000000)b

            So here 1 gets shifted outof the MSB

            1 Reply Last reply
            0
            • _ __yash__

              unsigned long i; //4-bytes, int: 4-bytes
              short s; //2-bytes
              signed char c; //1-byte

              i = (s<<15) + (c <<9);

              How will type conversion take place in this case? Is it that: 1. s will remain short(2 bytes) thus shifting the LSB into the MSB and remaining bits turn 0; c is promoted to short then left-shift 9 performed. The final R-value is promoted to unsigned long and saved into i. or 2. s and c both get converted to unsigned long before performing the shift operation (thus we do not lose any of the left-shifted bits) or something else happens. I tried it in VS6.0 and the result seem to indicate that in both s and c I did not lose any bit upon left-shifting as if s and c acted as if they were a 4-byte data type (long or int)

              A Offline
              A Offline
              Adam Roderick J
              wrote on last edited by
              #6

              please have look on the msdn [^]

              Величие не Бога может быть недооценена.

              1 Reply Last reply
              0
              • C CPallini

                Ralph_2 wrote:

                but then the evaluated values have to be stored back into their respective variables

                Nope. Why do you think that?

                If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                [My articles]

                _ Offline
                _ Offline
                __yash__
                wrote on last edited by
                #7

                Do you mean to say that since these are R-values they themselves do not get modified. Well, yes, my mistake. R-values will not be altered. My statement is incorrect. So now that we are talking at register-level then where and how does C's rules of type conversion come into picture?

                C 1 Reply Last reply
                0
                • _ __yash__

                  Do you mean to say that since these are R-values they themselves do not get modified. Well, yes, my mistake. R-values will not be altered. My statement is incorrect. So now that we are talking at register-level then where and how does C's rules of type conversion come into picture?

                  C Offline
                  C Offline
                  CPallini
                  wrote on last edited by
                  #8

                  Without talking about registers, types promotion occurs because of (in the original expression) the assignment was done to an integer. [edit] actually, running the following code

                  unsigned int u = 0xFFFFFFFF;
                  unsigned long long ul = (u << 8);

                  make me think the above expression cannot be true :^) [/edit] :)

                  If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                  This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                  [My articles]

                  modified on Thursday, October 22, 2009 4:08 AM

                  _ 1 Reply Last reply
                  0
                  • C CPallini

                    Without talking about registers, types promotion occurs because of (in the original expression) the assignment was done to an integer. [edit] actually, running the following code

                    unsigned int u = 0xFFFFFFFF;
                    unsigned long long ul = (u << 8);

                    make me think the above expression cannot be true :^) [/edit] :)

                    If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                    This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                    [My articles]

                    modified on Thursday, October 22, 2009 4:08 AM

                    _ Offline
                    _ Offline
                    __yash__
                    wrote on last edited by
                    #9

                    In the book C-The Complete Reference by Herbert Schildt theree is an example

                    char ch;
                    int i;
                    float f
                    double d;
                    result=(ch/i)+(f*d)-(f+i)

                    Here it does not talk about the data type of the variable "result". In any case, the conversion here is as follows: First ch is converted to int since i is int, then ch/i is performed. The result of ch/i is then converted to double as f*d is double. The final value is a double. Now if "result" is type float then the final value will be truncated to float and stored in "result", isnt it?

                    CPallini wrote:

                    types promotion occurs because of (in the original expressio) the assignment was done to an integer.

                    As we see in the above example the variable to which the final value is assigned, its type matters only when we have solved the expression on the right side. Please correct me if wrong anywhere. The mentioned book also says: "First, all char and short int values are automatically elevated to int" This seems to be the reason why I don't lose the shifted out bits and also because I store the value back in an unsigned long :)

                    modified on Thursday, October 22, 2009 4:51 AM

                    C 2 Replies Last reply
                    0
                    • _ __yash__

                      In the book C-The Complete Reference by Herbert Schildt theree is an example

                      char ch;
                      int i;
                      float f
                      double d;
                      result=(ch/i)+(f*d)-(f+i)

                      Here it does not talk about the data type of the variable "result". In any case, the conversion here is as follows: First ch is converted to int since i is int, then ch/i is performed. The result of ch/i is then converted to double as f*d is double. The final value is a double. Now if "result" is type float then the final value will be truncated to float and stored in "result", isnt it?

                      CPallini wrote:

                      types promotion occurs because of (in the original expressio) the assignment was done to an integer.

                      As we see in the above example the variable to which the final value is assigned, its type matters only when we have solved the expression on the right side. Please correct me if wrong anywhere. The mentioned book also says: "First, all char and short int values are automatically elevated to int" This seems to be the reason why I don't lose the shifted out bits and also because I store the value back in an unsigned long :)

                      modified on Thursday, October 22, 2009 4:51 AM

                      C Offline
                      C Offline
                      CPallini
                      wrote on last edited by
                      #10

                      Ralph_2 wrote:

                      Now if "result" is type float then the final value will be truncated to float and stored in "result", isnt it?

                      Yes (and the compiler warns about).

                      Ralph_2 wrote:

                      As we see in the above example the variable to which the final value is assigned, its type matters only when we have solved the expression on the right side.

                      Yes. As I added in my previous post, you're right and looks like registers matter... :)

                      If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                      This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                      [My articles]

                      1 Reply Last reply
                      0
                      • _ __yash__

                        In the book C-The Complete Reference by Herbert Schildt theree is an example

                        char ch;
                        int i;
                        float f
                        double d;
                        result=(ch/i)+(f*d)-(f+i)

                        Here it does not talk about the data type of the variable "result". In any case, the conversion here is as follows: First ch is converted to int since i is int, then ch/i is performed. The result of ch/i is then converted to double as f*d is double. The final value is a double. Now if "result" is type float then the final value will be truncated to float and stored in "result", isnt it?

                        CPallini wrote:

                        types promotion occurs because of (in the original expressio) the assignment was done to an integer.

                        As we see in the above example the variable to which the final value is assigned, its type matters only when we have solved the expression on the right side. Please correct me if wrong anywhere. The mentioned book also says: "First, all char and short int values are automatically elevated to int" This seems to be the reason why I don't lose the shifted out bits and also because I store the value back in an unsigned long :)

                        modified on Thursday, October 22, 2009 4:51 AM

                        C Offline
                        C Offline
                        CPallini
                        wrote on last edited by
                        #11

                        Ralph_2 wrote:

                        "First, all char and short int values are automatically elevated to int"

                        Yes, and it is also explained here [^]. I didn't know int had such a special role. :)

                        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                        This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                        [My articles]

                        _ 1 Reply Last reply
                        0
                        • C CPallini

                          Ralph_2 wrote:

                          "First, all char and short int values are automatically elevated to int"

                          Yes, and it is also explained here [^]. I didn't know int had such a special role. :)

                          If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                          This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                          [My articles]

                          _ Offline
                          _ Offline
                          __yash__
                          wrote on last edited by
                          #12

                          Thanks for your assistance. So the answer to my question is "Integral promotion" :) Now, if only int were 2-bytes then I lose the left-shifted bits and will have a different result for unsigned long = (short<<15) + (char<<9).....Ahem, i hope this is right now ;P

                          1 Reply Last reply
                          0
                          • _ __yash__

                            I understand that the shifts take place in registers but then the evaluated values have to be stored back into their respective variables, which are of type short and char, which cannot hold 4-byte values.

                            _ Offline
                            _ Offline
                            _Superman_
                            wrote on last edited by
                            #13

                            This is the assembly output for the statement i = (s << 15) + (c << 9);

                            movsx eax, WORD PTR _s$[ebp]
                            shl eax, 15 ; 0000000fH
                            movsx ecx, BYTE PTR _c$[ebp]
                            shl ecx, 9
                            add eax, ecx
                            mov DWORD PTR _i$[ebp], eax

                            So as you can see nothing is stored back into any variable. The two shifts happen in the eax and ecx registers. It is then added together and the stored into the variable i, which is also 4 bytes in length.

                            «_Superman_» I love work. It gives me something to do between weekends.
                            Microsoft MVP (Visual C++)

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups