Why references to the same constant take distinct memory space in C++?












3















I'm new to the idea of reference in C++, I have a question concerning the memory allocation of reference to a pure number constant. (Another thing I want to check first is that I suspect const reference, which I frequently came across, means reference to const, but I'm not sure.)



Here is my testing on ideone.com:



#include <stdio.h>

int main() {

const int r0 = 123;
const int &r1 = 123;
const int &r2 = 123;
const int &r3 = r2;

printf("%pn", (void *)&r0);
printf("%pn", (void *)&r1);
printf("%pn", (void *)&r2);
printf("%pn", (void *)&r3);

return 0;
}


and the result:



0x7ffee3bd74c4
0x7ffee3bd74c8
0x7ffee3bd74cc
0x7ffee3bd74cc


The reason r2 is the same as r3 is clear from this answer - How does a C++ reference look, memory-wise?, which says it's depending on compiler. But I'm thinking about why compiler doesn't also make r0,r1,r2 all the same, since all have the same pure constant value 123. (or called prvalue if no wrong search)



As a note: After some search on this site, I found a most related question - but in python. Although different language but I thought the idea should be the same/similar: from the link, if my program were written in python then there will be only one 123 is in the memory space for saving space.



Some other answers I've read:





  1. C++ do references occupy memory: This answer suggests that if it's necessary then int &x is implemented as *(pointer_to_x).


  2. How does a C++ reference look, memory-wise?: This answer suggests that compiler will try its best to save space.










share|improve this question

























  • I suspect the answer is because you ran the code without turning on any optimizations.

    – Mooing Duck
    Nov 22 '18 at 0:05











  • @MooingDuck: I was (re-)thinking about whether C++ would do the optimization as python before I fell asleep, then now I just wake up and realize that it should be either the converse/reverse question or C++ should handle it better. What's the canonical way/mechanism when C++ doing this?

    – ptr_NE
    Nov 22 '18 at 3:57








  • 1





    By default, compilers generate unoptimized builds, which make it far easier to step through and debug. However, every compiler also has a flag you can pass telling it to build an optimized build, which will shrink it down and make it fast and small. How are you compiling your code?

    – Mooing Duck
    Nov 22 '18 at 6:05











  • @MooingDuck: I just clicked run on ideone.com, I did try to find so called optimization options there but it seems like they don't have one. I haven't learned much about optimization since I rarely thinking about optimization.

    – ptr_NE
    Nov 22 '18 at 6:11






  • 1





    ptr_user7813604 coliru.stacked-crooked.com lets you pass -O0 through -O3 flags to the compiler, letting you see various results. (-O0 is the default of no optimization, -O3 is the maximum optimizations)

    – Mooing Duck
    Nov 22 '18 at 7:14


















3















I'm new to the idea of reference in C++, I have a question concerning the memory allocation of reference to a pure number constant. (Another thing I want to check first is that I suspect const reference, which I frequently came across, means reference to const, but I'm not sure.)



Here is my testing on ideone.com:



#include <stdio.h>

int main() {

const int r0 = 123;
const int &r1 = 123;
const int &r2 = 123;
const int &r3 = r2;

printf("%pn", (void *)&r0);
printf("%pn", (void *)&r1);
printf("%pn", (void *)&r2);
printf("%pn", (void *)&r3);

return 0;
}


and the result:



0x7ffee3bd74c4
0x7ffee3bd74c8
0x7ffee3bd74cc
0x7ffee3bd74cc


The reason r2 is the same as r3 is clear from this answer - How does a C++ reference look, memory-wise?, which says it's depending on compiler. But I'm thinking about why compiler doesn't also make r0,r1,r2 all the same, since all have the same pure constant value 123. (or called prvalue if no wrong search)



As a note: After some search on this site, I found a most related question - but in python. Although different language but I thought the idea should be the same/similar: from the link, if my program were written in python then there will be only one 123 is in the memory space for saving space.



Some other answers I've read:





  1. C++ do references occupy memory: This answer suggests that if it's necessary then int &x is implemented as *(pointer_to_x).


  2. How does a C++ reference look, memory-wise?: This answer suggests that compiler will try its best to save space.










share|improve this question

























  • I suspect the answer is because you ran the code without turning on any optimizations.

    – Mooing Duck
    Nov 22 '18 at 0:05











  • @MooingDuck: I was (re-)thinking about whether C++ would do the optimization as python before I fell asleep, then now I just wake up and realize that it should be either the converse/reverse question or C++ should handle it better. What's the canonical way/mechanism when C++ doing this?

    – ptr_NE
    Nov 22 '18 at 3:57








  • 1





    By default, compilers generate unoptimized builds, which make it far easier to step through and debug. However, every compiler also has a flag you can pass telling it to build an optimized build, which will shrink it down and make it fast and small. How are you compiling your code?

    – Mooing Duck
    Nov 22 '18 at 6:05











  • @MooingDuck: I just clicked run on ideone.com, I did try to find so called optimization options there but it seems like they don't have one. I haven't learned much about optimization since I rarely thinking about optimization.

    – ptr_NE
    Nov 22 '18 at 6:11






  • 1





    ptr_user7813604 coliru.stacked-crooked.com lets you pass -O0 through -O3 flags to the compiler, letting you see various results. (-O0 is the default of no optimization, -O3 is the maximum optimizations)

    – Mooing Duck
    Nov 22 '18 at 7:14
















3












3








3








I'm new to the idea of reference in C++, I have a question concerning the memory allocation of reference to a pure number constant. (Another thing I want to check first is that I suspect const reference, which I frequently came across, means reference to const, but I'm not sure.)



Here is my testing on ideone.com:



#include <stdio.h>

int main() {

const int r0 = 123;
const int &r1 = 123;
const int &r2 = 123;
const int &r3 = r2;

printf("%pn", (void *)&r0);
printf("%pn", (void *)&r1);
printf("%pn", (void *)&r2);
printf("%pn", (void *)&r3);

return 0;
}


and the result:



0x7ffee3bd74c4
0x7ffee3bd74c8
0x7ffee3bd74cc
0x7ffee3bd74cc


The reason r2 is the same as r3 is clear from this answer - How does a C++ reference look, memory-wise?, which says it's depending on compiler. But I'm thinking about why compiler doesn't also make r0,r1,r2 all the same, since all have the same pure constant value 123. (or called prvalue if no wrong search)



As a note: After some search on this site, I found a most related question - but in python. Although different language but I thought the idea should be the same/similar: from the link, if my program were written in python then there will be only one 123 is in the memory space for saving space.



Some other answers I've read:





  1. C++ do references occupy memory: This answer suggests that if it's necessary then int &x is implemented as *(pointer_to_x).


  2. How does a C++ reference look, memory-wise?: This answer suggests that compiler will try its best to save space.










share|improve this question
















I'm new to the idea of reference in C++, I have a question concerning the memory allocation of reference to a pure number constant. (Another thing I want to check first is that I suspect const reference, which I frequently came across, means reference to const, but I'm not sure.)



Here is my testing on ideone.com:



#include <stdio.h>

int main() {

const int r0 = 123;
const int &r1 = 123;
const int &r2 = 123;
const int &r3 = r2;

printf("%pn", (void *)&r0);
printf("%pn", (void *)&r1);
printf("%pn", (void *)&r2);
printf("%pn", (void *)&r3);

return 0;
}


and the result:



0x7ffee3bd74c4
0x7ffee3bd74c8
0x7ffee3bd74cc
0x7ffee3bd74cc


The reason r2 is the same as r3 is clear from this answer - How does a C++ reference look, memory-wise?, which says it's depending on compiler. But I'm thinking about why compiler doesn't also make r0,r1,r2 all the same, since all have the same pure constant value 123. (or called prvalue if no wrong search)



As a note: After some search on this site, I found a most related question - but in python. Although different language but I thought the idea should be the same/similar: from the link, if my program were written in python then there will be only one 123 is in the memory space for saving space.



Some other answers I've read:





  1. C++ do references occupy memory: This answer suggests that if it's necessary then int &x is implemented as *(pointer_to_x).


  2. How does a C++ reference look, memory-wise?: This answer suggests that compiler will try its best to save space.







c++ reference






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 '18 at 6:46







ptr_NE

















asked Nov 21 '18 at 22:52









ptr_NEptr_NE

603324




603324













  • I suspect the answer is because you ran the code without turning on any optimizations.

    – Mooing Duck
    Nov 22 '18 at 0:05











  • @MooingDuck: I was (re-)thinking about whether C++ would do the optimization as python before I fell asleep, then now I just wake up and realize that it should be either the converse/reverse question or C++ should handle it better. What's the canonical way/mechanism when C++ doing this?

    – ptr_NE
    Nov 22 '18 at 3:57








  • 1





    By default, compilers generate unoptimized builds, which make it far easier to step through and debug. However, every compiler also has a flag you can pass telling it to build an optimized build, which will shrink it down and make it fast and small. How are you compiling your code?

    – Mooing Duck
    Nov 22 '18 at 6:05











  • @MooingDuck: I just clicked run on ideone.com, I did try to find so called optimization options there but it seems like they don't have one. I haven't learned much about optimization since I rarely thinking about optimization.

    – ptr_NE
    Nov 22 '18 at 6:11






  • 1





    ptr_user7813604 coliru.stacked-crooked.com lets you pass -O0 through -O3 flags to the compiler, letting you see various results. (-O0 is the default of no optimization, -O3 is the maximum optimizations)

    – Mooing Duck
    Nov 22 '18 at 7:14





















  • I suspect the answer is because you ran the code without turning on any optimizations.

    – Mooing Duck
    Nov 22 '18 at 0:05











  • @MooingDuck: I was (re-)thinking about whether C++ would do the optimization as python before I fell asleep, then now I just wake up and realize that it should be either the converse/reverse question or C++ should handle it better. What's the canonical way/mechanism when C++ doing this?

    – ptr_NE
    Nov 22 '18 at 3:57








  • 1





    By default, compilers generate unoptimized builds, which make it far easier to step through and debug. However, every compiler also has a flag you can pass telling it to build an optimized build, which will shrink it down and make it fast and small. How are you compiling your code?

    – Mooing Duck
    Nov 22 '18 at 6:05











  • @MooingDuck: I just clicked run on ideone.com, I did try to find so called optimization options there but it seems like they don't have one. I haven't learned much about optimization since I rarely thinking about optimization.

    – ptr_NE
    Nov 22 '18 at 6:11






  • 1





    ptr_user7813604 coliru.stacked-crooked.com lets you pass -O0 through -O3 flags to the compiler, letting you see various results. (-O0 is the default of no optimization, -O3 is the maximum optimizations)

    – Mooing Duck
    Nov 22 '18 at 7:14



















I suspect the answer is because you ran the code without turning on any optimizations.

– Mooing Duck
Nov 22 '18 at 0:05





I suspect the answer is because you ran the code without turning on any optimizations.

– Mooing Duck
Nov 22 '18 at 0:05













@MooingDuck: I was (re-)thinking about whether C++ would do the optimization as python before I fell asleep, then now I just wake up and realize that it should be either the converse/reverse question or C++ should handle it better. What's the canonical way/mechanism when C++ doing this?

– ptr_NE
Nov 22 '18 at 3:57







@MooingDuck: I was (re-)thinking about whether C++ would do the optimization as python before I fell asleep, then now I just wake up and realize that it should be either the converse/reverse question or C++ should handle it better. What's the canonical way/mechanism when C++ doing this?

– ptr_NE
Nov 22 '18 at 3:57






1




1





By default, compilers generate unoptimized builds, which make it far easier to step through and debug. However, every compiler also has a flag you can pass telling it to build an optimized build, which will shrink it down and make it fast and small. How are you compiling your code?

– Mooing Duck
Nov 22 '18 at 6:05





By default, compilers generate unoptimized builds, which make it far easier to step through and debug. However, every compiler also has a flag you can pass telling it to build an optimized build, which will shrink it down and make it fast and small. How are you compiling your code?

– Mooing Duck
Nov 22 '18 at 6:05













@MooingDuck: I just clicked run on ideone.com, I did try to find so called optimization options there but it seems like they don't have one. I haven't learned much about optimization since I rarely thinking about optimization.

– ptr_NE
Nov 22 '18 at 6:11





@MooingDuck: I just clicked run on ideone.com, I did try to find so called optimization options there but it seems like they don't have one. I haven't learned much about optimization since I rarely thinking about optimization.

– ptr_NE
Nov 22 '18 at 6:11




1




1





ptr_user7813604 coliru.stacked-crooked.com lets you pass -O0 through -O3 flags to the compiler, letting you see various results. (-O0 is the default of no optimization, -O3 is the maximum optimizations)

– Mooing Duck
Nov 22 '18 at 7:14







ptr_user7813604 coliru.stacked-crooked.com lets you pass -O0 through -O3 flags to the compiler, letting you see various results. (-O0 is the default of no optimization, -O3 is the maximum optimizations)

– Mooing Duck
Nov 22 '18 at 7:14














3 Answers
3






active

oldest

votes


















6














Your 123 isn't a "constant". Rather, it is a literal. A literal forms an expression that is a prvalue (i.e. a temporary object initialized with the value of given by the literal). When you bind that expression to are reference, the lifetime of that object is extended to that of the reference, but the important point here is that each such object is a distinct object, and thus has a distinct address.



If you will, the text string "123" provides a rule for how to create objects, but it is not by itself an object. You can rewrite your code to make this more explicit:



const int & r = int(123);   // temporary of type "int" and value "123"


(There's no single such thing as "a constant" in C++. There are lots of things that are constant in one way or another, but they all need more detailed consideration.)






share|improve this answer
























  • So since const is just compile time checking it has nothing to do with constant?

    – ptr_NE
    Nov 21 '18 at 23:05






  • 1





    A prvalue is an expression, not a temporary object. Also there may or may not be a temporary object materialized at some stage for a prvalue. Reference binding causes temporary materialization.

    – M.M
    Nov 21 '18 at 23:18











  • @ptr_user7813604: I'd rather say that "constant" is too vague a term for that question to be meaningful. Lots of things can be constant in different ways in C++ (e.g. types, expressions, initialization).

    – Kerrek SB
    Nov 22 '18 at 0:56






  • 1





    @ptr_user7813604: Maybe it helps if you think of literals as being part of the source code, but object creation as part of the runtime behaviour? Source code doesn't create objects, only execution does. The source code (in this case, the literal) determines how objects are created at runtime. Temporary objects are distinct by their very nature; a temporary object has no aliases. No two unrelated expressions denote the same temporary object (until you start binding the temporary to some reference). That's how the language has been designed.

    – Kerrek SB
    Nov 22 '18 at 11:33






  • 1





    @ptr_user7813604: I'd say optimization is an unrelated topic that doesn't affect the present question, which is all about the object model and the nature of expressions in the language. All those are core parts of the C++ design. Ultimately the immediate answer is always "because that's how the language works", so perhaps a more satisfying question would be why the language has been designed this way. Temporary objects are not non-temporary objects in some global cache, they are truly temporary in the sense of being (newly, uniquely) created just at the point where they're needed.

    – Kerrek SB
    Nov 22 '18 at 11:55





















4














The literal is not an object. The references do not refer to the literal. When you initialise a reference using a literal, a temporary object will be created, and the lifetime of the temporary object is bound to the lifetime of the reference.



The objects (one local variable, two temporaries) are separate and distinct objects despite having the same value. Since they're separate, they occupy separate memory locations. The standard mandates this, and that makes it possible to identify and distinguish objects based on their memory address.






share|improve this answer

































    4














    The three declaration statements:



    const int &r1 = 123;
    const int &r2 = 123;
    const int &r3 = r2;


    will initialize 3 temporary objects with lifetime extended to be equal to the scope of their respective variables. Now, there is a language rule that says:




    Any two objects with overlapping lifetimes (that are not bit fields)
    are guaranteed to have different addresses unless one of them is a
    subobject of another or provides storage for another, or if they are
    subobjects of different type within the same complete object, and one
    of them is a zero-size base.




    Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses.



    Interestingly, the As-if rule might probably permit the program to allocate all three temporary objects at the same address but only if your compiler and linker can theoretically prove that your program can never observe the these objects as allocated at the same address. In your example, this is infeasible since you print the address of the objects.






    share|improve this answer
























    • This remind me of quantum mechanics in a sense that my observation is part of the experiment. By the way I have trouble to understand this kind of language rule, ... are guaranteed to ... for what?

      – ptr_NE
      Nov 22 '18 at 7:01








    • 1





      @ptr_user7813604 that's philosophical question and you will need to dive into C++ drafts and proposals to find answer. One of the probable reasons is that object identity can be used in computations - you can never distinguish r1 from r2 without having name if object they refer to is same.

      – Euri Pinhollow
      Nov 22 '18 at 7:47













    • OK I like this reason, and I will make a further induction that then the compiler can only do optimization up to a theoretical limit, where everything is almost indistinguishable. btw I like philosophical question because it doesn't necessarily have an answer.

      – ptr_NE
      Nov 22 '18 at 8:06













    • I don't understand your ["] Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses. [."], does it mean that some of them has the same address?

      – ptr_NE
      Nov 22 '18 at 8:16













    • @ptr_user7813604 "overlapping" refers not to the address of first byte but to the range of addresses objects occupy. This limitation means that no byte can be occupied by more than one object (except as said in excerpt).

      – Euri Pinhollow
      Nov 22 '18 at 11:46











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421559%2fwhy-references-to-the-same-constant-take-distinct-memory-space-in-c%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    6














    Your 123 isn't a "constant". Rather, it is a literal. A literal forms an expression that is a prvalue (i.e. a temporary object initialized with the value of given by the literal). When you bind that expression to are reference, the lifetime of that object is extended to that of the reference, but the important point here is that each such object is a distinct object, and thus has a distinct address.



    If you will, the text string "123" provides a rule for how to create objects, but it is not by itself an object. You can rewrite your code to make this more explicit:



    const int & r = int(123);   // temporary of type "int" and value "123"


    (There's no single such thing as "a constant" in C++. There are lots of things that are constant in one way or another, but they all need more detailed consideration.)






    share|improve this answer
























    • So since const is just compile time checking it has nothing to do with constant?

      – ptr_NE
      Nov 21 '18 at 23:05






    • 1





      A prvalue is an expression, not a temporary object. Also there may or may not be a temporary object materialized at some stage for a prvalue. Reference binding causes temporary materialization.

      – M.M
      Nov 21 '18 at 23:18











    • @ptr_user7813604: I'd rather say that "constant" is too vague a term for that question to be meaningful. Lots of things can be constant in different ways in C++ (e.g. types, expressions, initialization).

      – Kerrek SB
      Nov 22 '18 at 0:56






    • 1





      @ptr_user7813604: Maybe it helps if you think of literals as being part of the source code, but object creation as part of the runtime behaviour? Source code doesn't create objects, only execution does. The source code (in this case, the literal) determines how objects are created at runtime. Temporary objects are distinct by their very nature; a temporary object has no aliases. No two unrelated expressions denote the same temporary object (until you start binding the temporary to some reference). That's how the language has been designed.

      – Kerrek SB
      Nov 22 '18 at 11:33






    • 1





      @ptr_user7813604: I'd say optimization is an unrelated topic that doesn't affect the present question, which is all about the object model and the nature of expressions in the language. All those are core parts of the C++ design. Ultimately the immediate answer is always "because that's how the language works", so perhaps a more satisfying question would be why the language has been designed this way. Temporary objects are not non-temporary objects in some global cache, they are truly temporary in the sense of being (newly, uniquely) created just at the point where they're needed.

      – Kerrek SB
      Nov 22 '18 at 11:55


















    6














    Your 123 isn't a "constant". Rather, it is a literal. A literal forms an expression that is a prvalue (i.e. a temporary object initialized with the value of given by the literal). When you bind that expression to are reference, the lifetime of that object is extended to that of the reference, but the important point here is that each such object is a distinct object, and thus has a distinct address.



    If you will, the text string "123" provides a rule for how to create objects, but it is not by itself an object. You can rewrite your code to make this more explicit:



    const int & r = int(123);   // temporary of type "int" and value "123"


    (There's no single such thing as "a constant" in C++. There are lots of things that are constant in one way or another, but they all need more detailed consideration.)






    share|improve this answer
























    • So since const is just compile time checking it has nothing to do with constant?

      – ptr_NE
      Nov 21 '18 at 23:05






    • 1





      A prvalue is an expression, not a temporary object. Also there may or may not be a temporary object materialized at some stage for a prvalue. Reference binding causes temporary materialization.

      – M.M
      Nov 21 '18 at 23:18











    • @ptr_user7813604: I'd rather say that "constant" is too vague a term for that question to be meaningful. Lots of things can be constant in different ways in C++ (e.g. types, expressions, initialization).

      – Kerrek SB
      Nov 22 '18 at 0:56






    • 1





      @ptr_user7813604: Maybe it helps if you think of literals as being part of the source code, but object creation as part of the runtime behaviour? Source code doesn't create objects, only execution does. The source code (in this case, the literal) determines how objects are created at runtime. Temporary objects are distinct by their very nature; a temporary object has no aliases. No two unrelated expressions denote the same temporary object (until you start binding the temporary to some reference). That's how the language has been designed.

      – Kerrek SB
      Nov 22 '18 at 11:33






    • 1





      @ptr_user7813604: I'd say optimization is an unrelated topic that doesn't affect the present question, which is all about the object model and the nature of expressions in the language. All those are core parts of the C++ design. Ultimately the immediate answer is always "because that's how the language works", so perhaps a more satisfying question would be why the language has been designed this way. Temporary objects are not non-temporary objects in some global cache, they are truly temporary in the sense of being (newly, uniquely) created just at the point where they're needed.

      – Kerrek SB
      Nov 22 '18 at 11:55
















    6












    6








    6







    Your 123 isn't a "constant". Rather, it is a literal. A literal forms an expression that is a prvalue (i.e. a temporary object initialized with the value of given by the literal). When you bind that expression to are reference, the lifetime of that object is extended to that of the reference, but the important point here is that each such object is a distinct object, and thus has a distinct address.



    If you will, the text string "123" provides a rule for how to create objects, but it is not by itself an object. You can rewrite your code to make this more explicit:



    const int & r = int(123);   // temporary of type "int" and value "123"


    (There's no single such thing as "a constant" in C++. There are lots of things that are constant in one way or another, but they all need more detailed consideration.)






    share|improve this answer













    Your 123 isn't a "constant". Rather, it is a literal. A literal forms an expression that is a prvalue (i.e. a temporary object initialized with the value of given by the literal). When you bind that expression to are reference, the lifetime of that object is extended to that of the reference, but the important point here is that each such object is a distinct object, and thus has a distinct address.



    If you will, the text string "123" provides a rule for how to create objects, but it is not by itself an object. You can rewrite your code to make this more explicit:



    const int & r = int(123);   // temporary of type "int" and value "123"


    (There's no single such thing as "a constant" in C++. There are lots of things that are constant in one way or another, but they all need more detailed consideration.)







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 21 '18 at 22:58









    Kerrek SBKerrek SB

    364k61686916




    364k61686916













    • So since const is just compile time checking it has nothing to do with constant?

      – ptr_NE
      Nov 21 '18 at 23:05






    • 1





      A prvalue is an expression, not a temporary object. Also there may or may not be a temporary object materialized at some stage for a prvalue. Reference binding causes temporary materialization.

      – M.M
      Nov 21 '18 at 23:18











    • @ptr_user7813604: I'd rather say that "constant" is too vague a term for that question to be meaningful. Lots of things can be constant in different ways in C++ (e.g. types, expressions, initialization).

      – Kerrek SB
      Nov 22 '18 at 0:56






    • 1





      @ptr_user7813604: Maybe it helps if you think of literals as being part of the source code, but object creation as part of the runtime behaviour? Source code doesn't create objects, only execution does. The source code (in this case, the literal) determines how objects are created at runtime. Temporary objects are distinct by their very nature; a temporary object has no aliases. No two unrelated expressions denote the same temporary object (until you start binding the temporary to some reference). That's how the language has been designed.

      – Kerrek SB
      Nov 22 '18 at 11:33






    • 1





      @ptr_user7813604: I'd say optimization is an unrelated topic that doesn't affect the present question, which is all about the object model and the nature of expressions in the language. All those are core parts of the C++ design. Ultimately the immediate answer is always "because that's how the language works", so perhaps a more satisfying question would be why the language has been designed this way. Temporary objects are not non-temporary objects in some global cache, they are truly temporary in the sense of being (newly, uniquely) created just at the point where they're needed.

      – Kerrek SB
      Nov 22 '18 at 11:55





















    • So since const is just compile time checking it has nothing to do with constant?

      – ptr_NE
      Nov 21 '18 at 23:05






    • 1





      A prvalue is an expression, not a temporary object. Also there may or may not be a temporary object materialized at some stage for a prvalue. Reference binding causes temporary materialization.

      – M.M
      Nov 21 '18 at 23:18











    • @ptr_user7813604: I'd rather say that "constant" is too vague a term for that question to be meaningful. Lots of things can be constant in different ways in C++ (e.g. types, expressions, initialization).

      – Kerrek SB
      Nov 22 '18 at 0:56






    • 1





      @ptr_user7813604: Maybe it helps if you think of literals as being part of the source code, but object creation as part of the runtime behaviour? Source code doesn't create objects, only execution does. The source code (in this case, the literal) determines how objects are created at runtime. Temporary objects are distinct by their very nature; a temporary object has no aliases. No two unrelated expressions denote the same temporary object (until you start binding the temporary to some reference). That's how the language has been designed.

      – Kerrek SB
      Nov 22 '18 at 11:33






    • 1





      @ptr_user7813604: I'd say optimization is an unrelated topic that doesn't affect the present question, which is all about the object model and the nature of expressions in the language. All those are core parts of the C++ design. Ultimately the immediate answer is always "because that's how the language works", so perhaps a more satisfying question would be why the language has been designed this way. Temporary objects are not non-temporary objects in some global cache, they are truly temporary in the sense of being (newly, uniquely) created just at the point where they're needed.

      – Kerrek SB
      Nov 22 '18 at 11:55



















    So since const is just compile time checking it has nothing to do with constant?

    – ptr_NE
    Nov 21 '18 at 23:05





    So since const is just compile time checking it has nothing to do with constant?

    – ptr_NE
    Nov 21 '18 at 23:05




    1




    1





    A prvalue is an expression, not a temporary object. Also there may or may not be a temporary object materialized at some stage for a prvalue. Reference binding causes temporary materialization.

    – M.M
    Nov 21 '18 at 23:18





    A prvalue is an expression, not a temporary object. Also there may or may not be a temporary object materialized at some stage for a prvalue. Reference binding causes temporary materialization.

    – M.M
    Nov 21 '18 at 23:18













    @ptr_user7813604: I'd rather say that "constant" is too vague a term for that question to be meaningful. Lots of things can be constant in different ways in C++ (e.g. types, expressions, initialization).

    – Kerrek SB
    Nov 22 '18 at 0:56





    @ptr_user7813604: I'd rather say that "constant" is too vague a term for that question to be meaningful. Lots of things can be constant in different ways in C++ (e.g. types, expressions, initialization).

    – Kerrek SB
    Nov 22 '18 at 0:56




    1




    1





    @ptr_user7813604: Maybe it helps if you think of literals as being part of the source code, but object creation as part of the runtime behaviour? Source code doesn't create objects, only execution does. The source code (in this case, the literal) determines how objects are created at runtime. Temporary objects are distinct by their very nature; a temporary object has no aliases. No two unrelated expressions denote the same temporary object (until you start binding the temporary to some reference). That's how the language has been designed.

    – Kerrek SB
    Nov 22 '18 at 11:33





    @ptr_user7813604: Maybe it helps if you think of literals as being part of the source code, but object creation as part of the runtime behaviour? Source code doesn't create objects, only execution does. The source code (in this case, the literal) determines how objects are created at runtime. Temporary objects are distinct by their very nature; a temporary object has no aliases. No two unrelated expressions denote the same temporary object (until you start binding the temporary to some reference). That's how the language has been designed.

    – Kerrek SB
    Nov 22 '18 at 11:33




    1




    1





    @ptr_user7813604: I'd say optimization is an unrelated topic that doesn't affect the present question, which is all about the object model and the nature of expressions in the language. All those are core parts of the C++ design. Ultimately the immediate answer is always "because that's how the language works", so perhaps a more satisfying question would be why the language has been designed this way. Temporary objects are not non-temporary objects in some global cache, they are truly temporary in the sense of being (newly, uniquely) created just at the point where they're needed.

    – Kerrek SB
    Nov 22 '18 at 11:55







    @ptr_user7813604: I'd say optimization is an unrelated topic that doesn't affect the present question, which is all about the object model and the nature of expressions in the language. All those are core parts of the C++ design. Ultimately the immediate answer is always "because that's how the language works", so perhaps a more satisfying question would be why the language has been designed this way. Temporary objects are not non-temporary objects in some global cache, they are truly temporary in the sense of being (newly, uniquely) created just at the point where they're needed.

    – Kerrek SB
    Nov 22 '18 at 11:55















    4














    The literal is not an object. The references do not refer to the literal. When you initialise a reference using a literal, a temporary object will be created, and the lifetime of the temporary object is bound to the lifetime of the reference.



    The objects (one local variable, two temporaries) are separate and distinct objects despite having the same value. Since they're separate, they occupy separate memory locations. The standard mandates this, and that makes it possible to identify and distinguish objects based on their memory address.






    share|improve this answer






























      4














      The literal is not an object. The references do not refer to the literal. When you initialise a reference using a literal, a temporary object will be created, and the lifetime of the temporary object is bound to the lifetime of the reference.



      The objects (one local variable, two temporaries) are separate and distinct objects despite having the same value. Since they're separate, they occupy separate memory locations. The standard mandates this, and that makes it possible to identify and distinguish objects based on their memory address.






      share|improve this answer




























        4












        4








        4







        The literal is not an object. The references do not refer to the literal. When you initialise a reference using a literal, a temporary object will be created, and the lifetime of the temporary object is bound to the lifetime of the reference.



        The objects (one local variable, two temporaries) are separate and distinct objects despite having the same value. Since they're separate, they occupy separate memory locations. The standard mandates this, and that makes it possible to identify and distinguish objects based on their memory address.






        share|improve this answer















        The literal is not an object. The references do not refer to the literal. When you initialise a reference using a literal, a temporary object will be created, and the lifetime of the temporary object is bound to the lifetime of the reference.



        The objects (one local variable, two temporaries) are separate and distinct objects despite having the same value. Since they're separate, they occupy separate memory locations. The standard mandates this, and that makes it possible to identify and distinguish objects based on their memory address.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 21 '18 at 23:57

























        answered Nov 21 '18 at 23:00









        eerorikaeerorika

        78.2k556119




        78.2k556119























            4














            The three declaration statements:



            const int &r1 = 123;
            const int &r2 = 123;
            const int &r3 = r2;


            will initialize 3 temporary objects with lifetime extended to be equal to the scope of their respective variables. Now, there is a language rule that says:




            Any two objects with overlapping lifetimes (that are not bit fields)
            are guaranteed to have different addresses unless one of them is a
            subobject of another or provides storage for another, or if they are
            subobjects of different type within the same complete object, and one
            of them is a zero-size base.




            Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses.



            Interestingly, the As-if rule might probably permit the program to allocate all three temporary objects at the same address but only if your compiler and linker can theoretically prove that your program can never observe the these objects as allocated at the same address. In your example, this is infeasible since you print the address of the objects.






            share|improve this answer
























            • This remind me of quantum mechanics in a sense that my observation is part of the experiment. By the way I have trouble to understand this kind of language rule, ... are guaranteed to ... for what?

              – ptr_NE
              Nov 22 '18 at 7:01








            • 1





              @ptr_user7813604 that's philosophical question and you will need to dive into C++ drafts and proposals to find answer. One of the probable reasons is that object identity can be used in computations - you can never distinguish r1 from r2 without having name if object they refer to is same.

              – Euri Pinhollow
              Nov 22 '18 at 7:47













            • OK I like this reason, and I will make a further induction that then the compiler can only do optimization up to a theoretical limit, where everything is almost indistinguishable. btw I like philosophical question because it doesn't necessarily have an answer.

              – ptr_NE
              Nov 22 '18 at 8:06













            • I don't understand your ["] Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses. [."], does it mean that some of them has the same address?

              – ptr_NE
              Nov 22 '18 at 8:16













            • @ptr_user7813604 "overlapping" refers not to the address of first byte but to the range of addresses objects occupy. This limitation means that no byte can be occupied by more than one object (except as said in excerpt).

              – Euri Pinhollow
              Nov 22 '18 at 11:46
















            4














            The three declaration statements:



            const int &r1 = 123;
            const int &r2 = 123;
            const int &r3 = r2;


            will initialize 3 temporary objects with lifetime extended to be equal to the scope of their respective variables. Now, there is a language rule that says:




            Any two objects with overlapping lifetimes (that are not bit fields)
            are guaranteed to have different addresses unless one of them is a
            subobject of another or provides storage for another, or if they are
            subobjects of different type within the same complete object, and one
            of them is a zero-size base.




            Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses.



            Interestingly, the As-if rule might probably permit the program to allocate all three temporary objects at the same address but only if your compiler and linker can theoretically prove that your program can never observe the these objects as allocated at the same address. In your example, this is infeasible since you print the address of the objects.






            share|improve this answer
























            • This remind me of quantum mechanics in a sense that my observation is part of the experiment. By the way I have trouble to understand this kind of language rule, ... are guaranteed to ... for what?

              – ptr_NE
              Nov 22 '18 at 7:01








            • 1





              @ptr_user7813604 that's philosophical question and you will need to dive into C++ drafts and proposals to find answer. One of the probable reasons is that object identity can be used in computations - you can never distinguish r1 from r2 without having name if object they refer to is same.

              – Euri Pinhollow
              Nov 22 '18 at 7:47













            • OK I like this reason, and I will make a further induction that then the compiler can only do optimization up to a theoretical limit, where everything is almost indistinguishable. btw I like philosophical question because it doesn't necessarily have an answer.

              – ptr_NE
              Nov 22 '18 at 8:06













            • I don't understand your ["] Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses. [."], does it mean that some of them has the same address?

              – ptr_NE
              Nov 22 '18 at 8:16













            • @ptr_user7813604 "overlapping" refers not to the address of first byte but to the range of addresses objects occupy. This limitation means that no byte can be occupied by more than one object (except as said in excerpt).

              – Euri Pinhollow
              Nov 22 '18 at 11:46














            4












            4








            4







            The three declaration statements:



            const int &r1 = 123;
            const int &r2 = 123;
            const int &r3 = r2;


            will initialize 3 temporary objects with lifetime extended to be equal to the scope of their respective variables. Now, there is a language rule that says:




            Any two objects with overlapping lifetimes (that are not bit fields)
            are guaranteed to have different addresses unless one of them is a
            subobject of another or provides storage for another, or if they are
            subobjects of different type within the same complete object, and one
            of them is a zero-size base.




            Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses.



            Interestingly, the As-if rule might probably permit the program to allocate all three temporary objects at the same address but only if your compiler and linker can theoretically prove that your program can never observe the these objects as allocated at the same address. In your example, this is infeasible since you print the address of the objects.






            share|improve this answer













            The three declaration statements:



            const int &r1 = 123;
            const int &r2 = 123;
            const int &r3 = r2;


            will initialize 3 temporary objects with lifetime extended to be equal to the scope of their respective variables. Now, there is a language rule that says:




            Any two objects with overlapping lifetimes (that are not bit fields)
            are guaranteed to have different addresses unless one of them is a
            subobject of another or provides storage for another, or if they are
            subobjects of different type within the same complete object, and one
            of them is a zero-size base.




            Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses.



            Interestingly, the As-if rule might probably permit the program to allocate all three temporary objects at the same address but only if your compiler and linker can theoretically prove that your program can never observe the these objects as allocated at the same address. In your example, this is infeasible since you print the address of the objects.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 22 '18 at 0:26









            Julien Villemure-FréchetteJulien Villemure-Fréchette

            45517




            45517













            • This remind me of quantum mechanics in a sense that my observation is part of the experiment. By the way I have trouble to understand this kind of language rule, ... are guaranteed to ... for what?

              – ptr_NE
              Nov 22 '18 at 7:01








            • 1





              @ptr_user7813604 that's philosophical question and you will need to dive into C++ drafts and proposals to find answer. One of the probable reasons is that object identity can be used in computations - you can never distinguish r1 from r2 without having name if object they refer to is same.

              – Euri Pinhollow
              Nov 22 '18 at 7:47













            • OK I like this reason, and I will make a further induction that then the compiler can only do optimization up to a theoretical limit, where everything is almost indistinguishable. btw I like philosophical question because it doesn't necessarily have an answer.

              – ptr_NE
              Nov 22 '18 at 8:06













            • I don't understand your ["] Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses. [."], does it mean that some of them has the same address?

              – ptr_NE
              Nov 22 '18 at 8:16













            • @ptr_user7813604 "overlapping" refers not to the address of first byte but to the range of addresses objects occupy. This limitation means that no byte can be occupied by more than one object (except as said in excerpt).

              – Euri Pinhollow
              Nov 22 '18 at 11:46



















            • This remind me of quantum mechanics in a sense that my observation is part of the experiment. By the way I have trouble to understand this kind of language rule, ... are guaranteed to ... for what?

              – ptr_NE
              Nov 22 '18 at 7:01








            • 1





              @ptr_user7813604 that's philosophical question and you will need to dive into C++ drafts and proposals to find answer. One of the probable reasons is that object identity can be used in computations - you can never distinguish r1 from r2 without having name if object they refer to is same.

              – Euri Pinhollow
              Nov 22 '18 at 7:47













            • OK I like this reason, and I will make a further induction that then the compiler can only do optimization up to a theoretical limit, where everything is almost indistinguishable. btw I like philosophical question because it doesn't necessarily have an answer.

              – ptr_NE
              Nov 22 '18 at 8:06













            • I don't understand your ["] Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses. [."], does it mean that some of them has the same address?

              – ptr_NE
              Nov 22 '18 at 8:16













            • @ptr_user7813604 "overlapping" refers not to the address of first byte but to the range of addresses objects occupy. This limitation means that no byte can be occupied by more than one object (except as said in excerpt).

              – Euri Pinhollow
              Nov 22 '18 at 11:46

















            This remind me of quantum mechanics in a sense that my observation is part of the experiment. By the way I have trouble to understand this kind of language rule, ... are guaranteed to ... for what?

            – ptr_NE
            Nov 22 '18 at 7:01







            This remind me of quantum mechanics in a sense that my observation is part of the experiment. By the way I have trouble to understand this kind of language rule, ... are guaranteed to ... for what?

            – ptr_NE
            Nov 22 '18 at 7:01






            1




            1





            @ptr_user7813604 that's philosophical question and you will need to dive into C++ drafts and proposals to find answer. One of the probable reasons is that object identity can be used in computations - you can never distinguish r1 from r2 without having name if object they refer to is same.

            – Euri Pinhollow
            Nov 22 '18 at 7:47







            @ptr_user7813604 that's philosophical question and you will need to dive into C++ drafts and proposals to find answer. One of the probable reasons is that object identity can be used in computations - you can never distinguish r1 from r2 without having name if object they refer to is same.

            – Euri Pinhollow
            Nov 22 '18 at 7:47















            OK I like this reason, and I will make a further induction that then the compiler can only do optimization up to a theoretical limit, where everything is almost indistinguishable. btw I like philosophical question because it doesn't necessarily have an answer.

            – ptr_NE
            Nov 22 '18 at 8:06







            OK I like this reason, and I will make a further induction that then the compiler can only do optimization up to a theoretical limit, where everything is almost indistinguishable. btw I like philosophical question because it doesn't necessarily have an answer.

            – ptr_NE
            Nov 22 '18 at 8:06















            I don't understand your ["] Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses. [."], does it mean that some of them has the same address?

            – ptr_NE
            Nov 22 '18 at 8:16







            I don't understand your ["] Since the references are bound to 3 distinct temporary, then you cannot observe these objects on overlapping addresses. [."], does it mean that some of them has the same address?

            – ptr_NE
            Nov 22 '18 at 8:16















            @ptr_user7813604 "overlapping" refers not to the address of first byte but to the range of addresses objects occupy. This limitation means that no byte can be occupied by more than one object (except as said in excerpt).

            – Euri Pinhollow
            Nov 22 '18 at 11:46





            @ptr_user7813604 "overlapping" refers not to the address of first byte but to the range of addresses objects occupy. This limitation means that no byte can be occupied by more than one object (except as said in excerpt).

            – Euri Pinhollow
            Nov 22 '18 at 11:46


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421559%2fwhy-references-to-the-same-constant-take-distinct-memory-space-in-c%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Wiesbaden

            Marschland

            Dieringhausen