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. reference to const int

reference to const int

Scheduled Pinned Locked Moved C / C++ / MFC
questionperformance
21 Posts 7 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.
  • T ThatsAlok

    Which compiler are you using is it VS or something else?

    "Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
    Never mind - my own stupidity is the source of every "problem" - Mixture

    cheers, Alok Gupta VC Forum Q&A :- I/IV Support CRY- Child Relief and You

    A Offline
    A Offline
    Aabid
    wrote on last edited by
    #3

    VS 2010, VC++.

    1 Reply Last reply
    0
    • A Aabid

      void main() { const int i = 10; int& j = (int&)i; cout << "i= " << i << endl; cout << "j= " << j << endl; cout << "&i= " << &i << endl; cout << "&j= " << &j << endl; j++; cout << "j= " << j << endl; cout << "i= " << i << endl; } //output i= 10 j= 10 &i= 0012FF60 &j= 0012FF60 j= 11 i= 10 Hi, the code declares a const integer and a reference to it. incrementing a reference adds 1 to j and outputs as 11, that is fine. i was expecting "i" to get modified, since "i" and "j", both having a same memory address, as i print "i", it outputs 10 (or compiler should not allow to increment j). i could not understand the behavior. Could anybody explains me what is going on behind the scene? regards Abid

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #4

      If you generate the assembler listing for this code you can see that any reference to i in the code uses the constant value 10, but references to j use a memory variable, initially having a value of 10 but incremented as shown. I am not sure which language rule allows this but I would assume that since j is a reference to an integer then its target becomes a regular value. I have tried changing j to const int&, but the compiler objects with error C3892.

      Binding 100,000 items to a list box can be just silly regardless of what pattern you are following. Jeremy Likness

      1 Reply Last reply
      0
      • A Aabid

        void main() { const int i = 10; int& j = (int&)i; cout << "i= " << i << endl; cout << "j= " << j << endl; cout << "&i= " << &i << endl; cout << "&j= " << &j << endl; j++; cout << "j= " << j << endl; cout << "i= " << i << endl; } //output i= 10 j= 10 &i= 0012FF60 &j= 0012FF60 j= 11 i= 10 Hi, the code declares a const integer and a reference to it. incrementing a reference adds 1 to j and outputs as 11, that is fine. i was expecting "i" to get modified, since "i" and "j", both having a same memory address, as i print "i", it outputs 10 (or compiler should not allow to increment j). i could not understand the behavior. Could anybody explains me what is going on behind the scene? regards Abid

        C Offline
        C Offline
        Code o mat
        wrote on last edited by
        #5

        Additionally to what Richard said, if you change your const int i = 10; to volatile const int i = 10; then you get the expected result (outputting both i and j gives you 11 in the end).

        > The problem with computers is that they do what you tell them to do and not what you want them to do. < > If it doesn't matter, it's antimatter.<

        A 1 Reply Last reply
        0
        • A Aabid

          void main() { const int i = 10; int& j = (int&)i; cout << "i= " << i << endl; cout << "j= " << j << endl; cout << "&i= " << &i << endl; cout << "&j= " << &j << endl; j++; cout << "j= " << j << endl; cout << "i= " << i << endl; } //output i= 10 j= 10 &i= 0012FF60 &j= 0012FF60 j= 11 i= 10 Hi, the code declares a const integer and a reference to it. incrementing a reference adds 1 to j and outputs as 11, that is fine. i was expecting "i" to get modified, since "i" and "j", both having a same memory address, as i print "i", it outputs 10 (or compiler should not allow to increment j). i could not understand the behavior. Could anybody explains me what is going on behind the scene? regards Abid

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

          I don't know if (by the C++ specifications) that is the correct behaviour, however both the compiler provided by Visual Studio 2005 and g++ 4.4.3 gave me the same results you obtained. Apparently (even with optimizations turned off) the compiler replaces each occurrence of i with the literal value 10, making all the changes you perform on the corrensponding memeory address irrelevant. Compare the code generated for j and i in the cout lines: j

          cout << "j= " << j << endl;
          0041143A mov eax,dword ptr [__imp_std::endl (4182B4h)]
          0041143F push eax
          00411440 mov ecx,dword ptr [j] <=============== MEMORY ADDRESS
          00411443 mov edx,dword ptr [ecx]
          00411445 push edx
          00411446 push offset string "j= " (41570Ch)
          0041144B mov eax,dword ptr [__imp_std::cout (4182BCh)]
          00411450 push eax
          00411451 call std::operator<<<std::char_traits<char> > (4110F0h)
          00411456 add esp,8
          00411459 mov ecx,eax
          0041145B call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (4182C0h)]
          00411461 mov ecx,eax
          00411463 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (4182C4h)]

          i

          cout << "i= " << i << endl;
          00411469 mov eax,dword ptr [__imp_std::endl (4182B4h)]
          0041146E push eax
          0041146F push 0Ah <================= LITERAL (10)
          00411471 push offset string "i= " (415710h)
          00411476 mov ecx,dword ptr [__imp_std::cout (4182BCh)]
          0041147C push ecx
          0041147D call std::operator<<<std::char_traits<char> > (4110F0h)
          00411482 add esp,8
          00411485 mov ecx,eax
          00411487 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (4182C0h)]
          0041148D mov ecx,eax
          0041148F call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (4182C4h)]

          Veni, vidi, vici.

          1 Reply Last reply
          0
          • A Aabid

            void main() { const int i = 10; int& j = (int&)i; cout << "i= " << i << endl; cout << "j= " << j << endl; cout << "&i= " << &i << endl; cout << "&j= " << &j << endl; j++; cout << "j= " << j << endl; cout << "i= " << i << endl; } //output i= 10 j= 10 &i= 0012FF60 &j= 0012FF60 j= 11 i= 10 Hi, the code declares a const integer and a reference to it. incrementing a reference adds 1 to j and outputs as 11, that is fine. i was expecting "i" to get modified, since "i" and "j", both having a same memory address, as i print "i", it outputs 10 (or compiler should not allow to increment j). i could not understand the behavior. Could anybody explains me what is going on behind the scene? regards Abid

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #7

            If you change your reference statement to:

            const int& j = i; // do not cast away const-ness

            you will not be allowed to increment the value of j as it is now a constant integer value and can only ever be 10.

            Binding 100,000 items to a list box can be just silly regardless of what pattern you are following. Jeremy Likness

            A 1 Reply Last reply
            0
            • L Lost User

              If you change your reference statement to:

              const int& j = i; // do not cast away const-ness

              you will not be allowed to increment the value of j as it is now a constant integer value and can only ever be 10.

              Binding 100,000 items to a list box can be just silly regardless of what pattern you are following. Jeremy Likness

              A Offline
              A Offline
              Aabid
              wrote on last edited by
              #8

              i know that, but i was trying to understand the previous behavior and that is still a mystery!

              L 1 Reply Last reply
              0
              • A Aabid

                i know that, but i was trying to understand the previous behavior and that is still a mystery!

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #9

                Aabid wrote:

                the previous behavior and that is still a mystery!

                Not really, in your original code you had:

                const int i = 10;
                int& j = (int&)i;

                so you are casting away the const-ness of i and effectively making j refer to a new variable, which starts out with the same value as i, but is modifiable since it is not a constant.

                Binding 100,000 items to a list box can be just silly regardless of what pattern you are following. Jeremy Likness

                A 1 Reply Last reply
                0
                • L Lost User

                  Aabid wrote:

                  the previous behavior and that is still a mystery!

                  Not really, in your original code you had:

                  const int i = 10;
                  int& j = (int&)i;

                  so you are casting away the const-ness of i and effectively making j refer to a new variable, which starts out with the same value as i, but is modifiable since it is not a constant.

                  Binding 100,000 items to a list box can be just silly regardless of what pattern you are following. Jeremy Likness

                  A Offline
                  A Offline
                  Aabid
                  wrote on last edited by
                  #10

                  But reference never creates a new variable, it is an alias to the same memory location, if you see the output of the code, you will see "i" and "j" have the same address. ok, if the following statement creates a new variable, is there any way to get the address of that variable? i tried to print &(int&)i, it still gives the same address as "i" and "j"; int& j = (int&)i;

                  L 1 Reply Last reply
                  0
                  • A Aabid

                    But reference never creates a new variable, it is an alias to the same memory location, if you see the output of the code, you will see "i" and "j" have the same address. ok, if the following statement creates a new variable, is there any way to get the address of that variable? i tried to print &(int&)i, it still gives the same address as "i" and "j"; int& j = (int&)i;

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #11

                    const int i = 10;

                    This statement declares to the compiler that every time it sees the name i in a line of source code, it should replace it with the value 10. You have caused confusion in your source by declaring j as a reference to a non-const value of 10. The two are not the same. You cannot cast away the const-ness of a value in this way and expect it to remain constant.

                    Binding 100,000 items to a list box can be just silly regardless of what pattern you are following. Jeremy Likness

                    1 Reply Last reply
                    0
                    • A Aabid

                      void main() { const int i = 10; int& j = (int&)i; cout << "i= " << i << endl; cout << "j= " << j << endl; cout << "&i= " << &i << endl; cout << "&j= " << &j << endl; j++; cout << "j= " << j << endl; cout << "i= " << i << endl; } //output i= 10 j= 10 &i= 0012FF60 &j= 0012FF60 j= 11 i= 10 Hi, the code declares a const integer and a reference to it. incrementing a reference adds 1 to j and outputs as 11, that is fine. i was expecting "i" to get modified, since "i" and "j", both having a same memory address, as i print "i", it outputs 10 (or compiler should not allow to increment j). i could not understand the behavior. Could anybody explains me what is going on behind the scene? regards Abid

                      A Offline
                      A Offline
                      Aescleal
                      wrote on last edited by
                      #12

                      If you take the address or reference of a const object and assign it to a non-const pointer or reference and you then modify the value through that pointer or reference the compiler can do whatever it wants. Even laugh at you or fire nuclear missiles (if it's got any) while twirling it's moustache. In C if you declare a constant it's just a read only variable. It has it's own memory location, everything's peachy and works the way you expect. In C++ it really is a constant for the rest of time. It'll never change. Wherever the compiler sees i it can (and probably does) just hardcode the value 10. So what happens when you bind a non-const reference to a const value? Well anything can. But in your compiler's case it cooks up an anonymous temporary variable with the same lifetime as the reference and assigns whatever the constant is to it. This also happens when you take the address of a const as well and assign it to a non-const pointer. What's actually happening is something like:

                      int x = 10;

                      cout << "i= " << 10 << endl;
                      cout << "j= " << x << endl;
                      cout << "&i= " << &x << endl;
                      cout << "&j= " << &x << endl;

                      x++;

                      cout << "j= " << x << endl;
                      cout << "i= " << 10 << endl;

                      The only way you're going to change i is to hunt through the executable code and change the immediate value there :-) Incidentally how this happens is non-portable, it happens on VC++ and GCC but other compilers might have slightly different takes on it.

                      1 Reply Last reply
                      0
                      • C Code o mat

                        Additionally to what Richard said, if you change your const int i = 10; to volatile const int i = 10; then you get the expected result (outputting both i and j gives you 11 in the end).

                        > The problem with computers is that they do what you tell them to do and not what you want them to do. < > If it doesn't matter, it's antimatter.<

                        A Offline
                        A Offline
                        Aescleal
                        wrote on last edited by
                        #13

                        The reason for that is that the compiler can't assume that i is fixed any more (you've told it that something somewhere could modify it) so there's a real variable behind it. You're still not allowed to modify it through i though! This sort of trick is really handy for overlaying C++ objects on ranges of addresses for memory mapped devices. Cheers, Ash

                        C 1 Reply Last reply
                        0
                        • A Aescleal

                          The reason for that is that the compiler can't assume that i is fixed any more (you've told it that something somewhere could modify it) so there's a real variable behind it. You're still not allowed to modify it through i though! This sort of trick is really handy for overlaying C++ objects on ranges of addresses for memory mapped devices. Cheers, Ash

                          C Offline
                          C Offline
                          Code o mat
                          wrote on last edited by
                          #14

                          Aescleal wrote:

                          The reason for that is that the compiler can't assume that i is fixed any more (you've told it that something somewhere could modify it) so there's a real variable behind it.

                          I know. :) As far as i know this basically means "don't keep in a register", so the compiler will do its best to keep the memory up-to-date.

                          Aescleal wrote:

                          You're still not allowed to modify it through i though! This sort of trick is really handy for overlaying C++ objects on ranges of addresses for memory mapped devices.

                          I think you shouldn't be able to do it, since usually things are declared as const for a reason, if you need to change them then don't make them const. But of course, there are those nasty situations when doing that can and will come in handy, like when you are using some 3rd party code you are not allowed (or simply don't want) to modify and try to call a method through a const pointer about which you know it does not change the object (like some simple Get method) and realize that the coder who created it kinda forgot to make the method const. Altrough this still might be dangerous because the method's implementation might change in the future and after the next update of the 3rd party library/codebase it borks everything...

                          > The problem with computers is that they do what you tell them to do and not what you want them to do. < > If it doesn't matter, it's antimatter.<

                          A J 2 Replies Last reply
                          0
                          • C Code o mat

                            Aescleal wrote:

                            The reason for that is that the compiler can't assume that i is fixed any more (you've told it that something somewhere could modify it) so there's a real variable behind it.

                            I know. :) As far as i know this basically means "don't keep in a register", so the compiler will do its best to keep the memory up-to-date.

                            Aescleal wrote:

                            You're still not allowed to modify it through i though! This sort of trick is really handy for overlaying C++ objects on ranges of addresses for memory mapped devices.

                            I think you shouldn't be able to do it, since usually things are declared as const for a reason, if you need to change them then don't make them const. But of course, there are those nasty situations when doing that can and will come in handy, like when you are using some 3rd party code you are not allowed (or simply don't want) to modify and try to call a method through a const pointer about which you know it does not change the object (like some simple Get method) and realize that the coder who created it kinda forgot to make the method const. Altrough this still might be dangerous because the method's implementation might change in the future and after the next update of the 3rd party library/codebase it borks everything...

                            > The problem with computers is that they do what you tell them to do and not what you want them to do. < > If it doesn't matter, it's antimatter.<

                            A Offline
                            A Offline
                            Aescleal
                            wrote on last edited by
                            #15

                            I've used this construct for accessing read only registers on an old data collection card. Despite the fact you couldn't write to them an esteemed colleague of mine decided to try anyway. So after making them const as well as volatile he couldn't any more. So it's been handy, er, once in my 23 year programming career. In 1994. It's about the only time I've used placement new as well! As you said, the whole const reference thing is there to make sure you can call things that idiot programmers wrote who didn't understand const. In my experience it's more common when you're calling (very) old C interfaces with pointers. Usually very old C code has an excuse as most C compilers before C90 didn't support const. Hmmm, wonder if it's worth having a C++FAQ on here, this one comes up at least once a year... Cheers, Ash

                            C 1 Reply Last reply
                            0
                            • A Aescleal

                              I've used this construct for accessing read only registers on an old data collection card. Despite the fact you couldn't write to them an esteemed colleague of mine decided to try anyway. So after making them const as well as volatile he couldn't any more. So it's been handy, er, once in my 23 year programming career. In 1994. It's about the only time I've used placement new as well! As you said, the whole const reference thing is there to make sure you can call things that idiot programmers wrote who didn't understand const. In my experience it's more common when you're calling (very) old C interfaces with pointers. Usually very old C code has an excuse as most C compilers before C90 didn't support const. Hmmm, wonder if it's worth having a C++FAQ on here, this one comes up at least once a year... Cheers, Ash

                              C Offline
                              C Offline
                              Code o mat
                              wrote on last edited by
                              #16

                              A FAQ? Hmm, that sounds like a good idea to me. There are many topics that seem to come up frequently...

                              > The problem with computers is that they do what you tell them to do and not what you want them to do. < > If it doesn't matter, it's antimatter.<

                              1 Reply Last reply
                              0
                              • C Code o mat

                                Aescleal wrote:

                                The reason for that is that the compiler can't assume that i is fixed any more (you've told it that something somewhere could modify it) so there's a real variable behind it.

                                I know. :) As far as i know this basically means "don't keep in a register", so the compiler will do its best to keep the memory up-to-date.

                                Aescleal wrote:

                                You're still not allowed to modify it through i though! This sort of trick is really handy for overlaying C++ objects on ranges of addresses for memory mapped devices.

                                I think you shouldn't be able to do it, since usually things are declared as const for a reason, if you need to change them then don't make them const. But of course, there are those nasty situations when doing that can and will come in handy, like when you are using some 3rd party code you are not allowed (or simply don't want) to modify and try to call a method through a const pointer about which you know it does not change the object (like some simple Get method) and realize that the coder who created it kinda forgot to make the method const. Altrough this still might be dangerous because the method's implementation might change in the future and after the next update of the 3rd party library/codebase it borks everything...

                                > The problem with computers is that they do what you tell them to do and not what you want them to do. < > If it doesn't matter, it's antimatter.<

                                J Offline
                                J Offline
                                jschell
                                wrote on last edited by
                                #17

                                Code-o-mat wrote:

                                I think you shouldn't be able to do it, since usually things are declared as const for a reason

                                Pretty sure that the mindset of C++ (and C) is that the developer is a responsible adult and thus they are responsible for the stupid things that they do.

                                C A 2 Replies Last reply
                                0
                                • J jschell

                                  Code-o-mat wrote:

                                  I think you shouldn't be able to do it, since usually things are declared as const for a reason

                                  Pretty sure that the mindset of C++ (and C) is that the developer is a responsible adult and thus they are responsible for the stupid things that they do.

                                  C Offline
                                  C Offline
                                  Code o mat
                                  wrote on last edited by
                                  #18

                                  That probably does carry some truth :) And that's why we love and hate C++

                                  > The problem with computers is that they do what you tell them to do and not what you want them to do. < > If it doesn't matter, it's antimatter.<

                                  1 Reply Last reply
                                  0
                                  • A Aabid

                                    void main() { const int i = 10; int& j = (int&)i; cout << "i= " << i << endl; cout << "j= " << j << endl; cout << "&i= " << &i << endl; cout << "&j= " << &j << endl; j++; cout << "j= " << j << endl; cout << "i= " << i << endl; } //output i= 10 j= 10 &i= 0012FF60 &j= 0012FF60 j= 11 i= 10 Hi, the code declares a const integer and a reference to it. incrementing a reference adds 1 to j and outputs as 11, that is fine. i was expecting "i" to get modified, since "i" and "j", both having a same memory address, as i print "i", it outputs 10 (or compiler should not allow to increment j). i could not understand the behavior. Could anybody explains me what is going on behind the scene? regards Abid

                                    J Offline
                                    J Offline
                                    jschell
                                    wrote on last edited by
                                    #19

                                    Aabid wrote:

                                    the code declares a const integer and a reference to it. incrementing a reference adds 1 to j and outputs as 11, that is fine.

                                    I don't see that it is "fine". The code is wrong - it shouldn't be written like that in the first place. Once one starts with that then the resulting behavior no longer matters. There are an infinite number of ways to write code incorrectly. There is a large, but finite, number of ways to write code correctly. Myself I don't care what the compiler does with incorrect code.

                                    1 Reply Last reply
                                    0
                                    • J jschell

                                      Code-o-mat wrote:

                                      I think you shouldn't be able to do it, since usually things are declared as const for a reason

                                      Pretty sure that the mindset of C++ (and C) is that the developer is a responsible adult and thus they are responsible for the stupid things that they do.

                                      A Offline
                                      A Offline
                                      Aescleal
                                      wrote on last edited by
                                      #20

                                      Responsible adult? You've never worked in the games industry :-) Biggest bunch of hackers (in the bad sense) out there.

                                      J 1 Reply Last reply
                                      0
                                      • A Aescleal

                                        Responsible adult? You've never worked in the games industry :-) Biggest bunch of hackers (in the bad sense) out there.

                                        J Offline
                                        J Offline
                                        jschell
                                        wrote on last edited by
                                        #21

                                        Aescleal wrote:

                                        Responsible adult? You've never worked in the games industry :) Biggest bunch of hackers (in the bad sense) out there.

                                        I do however have extensive telecom and financial experience and the same thing applies there.

                                        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