Confusion on operator overloading and heap vs stackWhat and where are the stack and heap?What are rvalues, lvalues, xvalues, glvalues, and prvalues?How to return a class object by reference in C++?Why doesn't Java offer operator overloading?What and where are the stack and heap?Which is faster: Stack allocation or Heap allocationWhat is the “-->” operator in C++?What are the basic rules and idioms for operator overloading?Basic operator overloading syntax in c++Confused with Java Memory Management (Stacks and Heaps)Const and Non-Const Operator OverloadingC++ template class and operator overloadingOverloading operator= in templated class

How do conventional missiles fly?

How badly should I try to prevent a user from XSSing themselves?

What method can I use to design a dungeon difficult enough that the PCs can't make it through without killing them?

Apex Framework / library for consuming REST services

What does “the session was packed” mean in this context?

Is it logically or scientifically possible to artificially send energy to the body?

Could the museum Saturn V's be refitted for one more flight?

Why would the Red Woman birth a shadow if she worshipped the Lord of the Light?

Which is the best way to check return result?

Examples of smooth manifolds admitting inbetween one and a continuum of complex structures

If human space travel is limited by the G force vulnerability, is there a way to counter G forces?

How writing a dominant 7 sus4 chord in RNA ( Vsus7 chord in the 1st inversion)

CAST throwing error when run in stored procedure but not when run as raw query

Im going to France and my passport expires June 19th

What mechanic is there to disable a threat instead of killing it?

What killed these X2 caps?

In 'Revenger,' what does 'cove' come from?

Why doesn't using multiple commands with a || or && conditional work?

Expand and Contract

Why didn't Miles's spider sense work before?

Reverse dictionary where values are lists

How dangerous is XSS?

ssTTsSTtRrriinInnnnNNNIiinngg

How does a predictive coding aid in lossless compression?



Confusion on operator overloading and heap vs stack


What and where are the stack and heap?What are rvalues, lvalues, xvalues, glvalues, and prvalues?How to return a class object by reference in C++?Why doesn't Java offer operator overloading?What and where are the stack and heap?Which is faster: Stack allocation or Heap allocationWhat is the “-->” operator in C++?What are the basic rules and idioms for operator overloading?Basic operator overloading syntax in c++Confused with Java Memory Management (Stacks and Heaps)Const and Non-Const Operator OverloadingC++ template class and operator overloadingOverloading operator= in templated class













0















I'm looking at the following tutorial:
http://www.videotutorialsrock.com/opengl_tutorial/animation/home.php



This person has a vector class:



class Vec3f 
private:
float v[3];
public:
Vec3f();
Vec3f(float x, float y, float z);

float &operator[](int index);
float operator[](int index) const;

Vec3f operator*(float scale) const;
Vec3f operator/(float scale) const;
Vec3f operator+(const Vec3f &other) const;
Vec3f operator-(const Vec3f &other) const;
Vec3f operator-() const;

const Vec3f &operator*=(float scale);
const Vec3f &operator/=(float scale);
const Vec3f &operator+=(const Vec3f &other);
const Vec3f &operator-=(const Vec3f &other);

float magnitude() const;
float magnitudeSquared() const;
Vec3f normalize() const;
float dot(const Vec3f &other) const;
Vec3f cross(const Vec3f &other) const;
;


With an example definition:



Vec3f Vec3f::operator*(float scale) const 
return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);



I'm confused on why this works. Shouldn't this immediately cause a segmentation fault? The return value is on the stack and should get deleted upon termination of all of these functions. Why does it work? Is my understanding of stack vs heap incorrect?



EDIT: I am basing my understanding from this:
How to return a class object by reference in C++?










share|improve this question



















  • 1





    If return values got destroyed before the function exited, what would be the point of return values?

    – alter igel
    Mar 7 at 22:47






  • 1





    But it's not being returned by reference. This is a plain old return by value. The object is being copied and it is trivially copyable so there's not much that can go wrong. Plus there is a lot of room for the compiler to eliminate the copy (See Copy Elision).

    – user4581301
    Mar 7 at 22:51







  • 2





    return by reference != return by copy/value. If you were returning by reference, you would indeed have undefined behavior (UB).

    – Jarod42
    Mar 7 at 22:51






  • 2





    @SpentDeath if your Vec3f had dynamically allocated member data, and followed the Rule of Three, then yes, it would be perfectly safe.

    – alter igel
    Mar 7 at 22:54






  • 2





    But if you do not follow the Rule of Three, then you are very likely smurfed one way or another. You have a memory leak or sooner or later there is a double delete. Your goal as a programmer should be to design your classes to observe the Rule of zero or hide all of the management through the Rules of Three and Five from users to that they can adhere to the Rule of Zero.

    – user4581301
    Mar 7 at 22:57
















0















I'm looking at the following tutorial:
http://www.videotutorialsrock.com/opengl_tutorial/animation/home.php



This person has a vector class:



class Vec3f 
private:
float v[3];
public:
Vec3f();
Vec3f(float x, float y, float z);

float &operator[](int index);
float operator[](int index) const;

Vec3f operator*(float scale) const;
Vec3f operator/(float scale) const;
Vec3f operator+(const Vec3f &other) const;
Vec3f operator-(const Vec3f &other) const;
Vec3f operator-() const;

const Vec3f &operator*=(float scale);
const Vec3f &operator/=(float scale);
const Vec3f &operator+=(const Vec3f &other);
const Vec3f &operator-=(const Vec3f &other);

float magnitude() const;
float magnitudeSquared() const;
Vec3f normalize() const;
float dot(const Vec3f &other) const;
Vec3f cross(const Vec3f &other) const;
;


With an example definition:



Vec3f Vec3f::operator*(float scale) const 
return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);



I'm confused on why this works. Shouldn't this immediately cause a segmentation fault? The return value is on the stack and should get deleted upon termination of all of these functions. Why does it work? Is my understanding of stack vs heap incorrect?



EDIT: I am basing my understanding from this:
How to return a class object by reference in C++?










share|improve this question



















  • 1





    If return values got destroyed before the function exited, what would be the point of return values?

    – alter igel
    Mar 7 at 22:47






  • 1





    But it's not being returned by reference. This is a plain old return by value. The object is being copied and it is trivially copyable so there's not much that can go wrong. Plus there is a lot of room for the compiler to eliminate the copy (See Copy Elision).

    – user4581301
    Mar 7 at 22:51







  • 2





    return by reference != return by copy/value. If you were returning by reference, you would indeed have undefined behavior (UB).

    – Jarod42
    Mar 7 at 22:51






  • 2





    @SpentDeath if your Vec3f had dynamically allocated member data, and followed the Rule of Three, then yes, it would be perfectly safe.

    – alter igel
    Mar 7 at 22:54






  • 2





    But if you do not follow the Rule of Three, then you are very likely smurfed one way or another. You have a memory leak or sooner or later there is a double delete. Your goal as a programmer should be to design your classes to observe the Rule of zero or hide all of the management through the Rules of Three and Five from users to that they can adhere to the Rule of Zero.

    – user4581301
    Mar 7 at 22:57














0












0








0








I'm looking at the following tutorial:
http://www.videotutorialsrock.com/opengl_tutorial/animation/home.php



This person has a vector class:



class Vec3f 
private:
float v[3];
public:
Vec3f();
Vec3f(float x, float y, float z);

float &operator[](int index);
float operator[](int index) const;

Vec3f operator*(float scale) const;
Vec3f operator/(float scale) const;
Vec3f operator+(const Vec3f &other) const;
Vec3f operator-(const Vec3f &other) const;
Vec3f operator-() const;

const Vec3f &operator*=(float scale);
const Vec3f &operator/=(float scale);
const Vec3f &operator+=(const Vec3f &other);
const Vec3f &operator-=(const Vec3f &other);

float magnitude() const;
float magnitudeSquared() const;
Vec3f normalize() const;
float dot(const Vec3f &other) const;
Vec3f cross(const Vec3f &other) const;
;


With an example definition:



Vec3f Vec3f::operator*(float scale) const 
return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);



I'm confused on why this works. Shouldn't this immediately cause a segmentation fault? The return value is on the stack and should get deleted upon termination of all of these functions. Why does it work? Is my understanding of stack vs heap incorrect?



EDIT: I am basing my understanding from this:
How to return a class object by reference in C++?










share|improve this question
















I'm looking at the following tutorial:
http://www.videotutorialsrock.com/opengl_tutorial/animation/home.php



This person has a vector class:



class Vec3f 
private:
float v[3];
public:
Vec3f();
Vec3f(float x, float y, float z);

float &operator[](int index);
float operator[](int index) const;

Vec3f operator*(float scale) const;
Vec3f operator/(float scale) const;
Vec3f operator+(const Vec3f &other) const;
Vec3f operator-(const Vec3f &other) const;
Vec3f operator-() const;

const Vec3f &operator*=(float scale);
const Vec3f &operator/=(float scale);
const Vec3f &operator+=(const Vec3f &other);
const Vec3f &operator-=(const Vec3f &other);

float magnitude() const;
float magnitudeSquared() const;
Vec3f normalize() const;
float dot(const Vec3f &other) const;
Vec3f cross(const Vec3f &other) const;
;


With an example definition:



Vec3f Vec3f::operator*(float scale) const 
return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);



I'm confused on why this works. Shouldn't this immediately cause a segmentation fault? The return value is on the stack and should get deleted upon termination of all of these functions. Why does it work? Is my understanding of stack vs heap incorrect?



EDIT: I am basing my understanding from this:
How to return a class object by reference in C++?







c++ memory-management operator-overloading heap-memory stack-memory






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 7 at 22:50







Spent Death

















asked Mar 7 at 22:40









Spent DeathSpent Death

295311




295311







  • 1





    If return values got destroyed before the function exited, what would be the point of return values?

    – alter igel
    Mar 7 at 22:47






  • 1





    But it's not being returned by reference. This is a plain old return by value. The object is being copied and it is trivially copyable so there's not much that can go wrong. Plus there is a lot of room for the compiler to eliminate the copy (See Copy Elision).

    – user4581301
    Mar 7 at 22:51







  • 2





    return by reference != return by copy/value. If you were returning by reference, you would indeed have undefined behavior (UB).

    – Jarod42
    Mar 7 at 22:51






  • 2





    @SpentDeath if your Vec3f had dynamically allocated member data, and followed the Rule of Three, then yes, it would be perfectly safe.

    – alter igel
    Mar 7 at 22:54






  • 2





    But if you do not follow the Rule of Three, then you are very likely smurfed one way or another. You have a memory leak or sooner or later there is a double delete. Your goal as a programmer should be to design your classes to observe the Rule of zero or hide all of the management through the Rules of Three and Five from users to that they can adhere to the Rule of Zero.

    – user4581301
    Mar 7 at 22:57













  • 1





    If return values got destroyed before the function exited, what would be the point of return values?

    – alter igel
    Mar 7 at 22:47






  • 1





    But it's not being returned by reference. This is a plain old return by value. The object is being copied and it is trivially copyable so there's not much that can go wrong. Plus there is a lot of room for the compiler to eliminate the copy (See Copy Elision).

    – user4581301
    Mar 7 at 22:51







  • 2





    return by reference != return by copy/value. If you were returning by reference, you would indeed have undefined behavior (UB).

    – Jarod42
    Mar 7 at 22:51






  • 2





    @SpentDeath if your Vec3f had dynamically allocated member data, and followed the Rule of Three, then yes, it would be perfectly safe.

    – alter igel
    Mar 7 at 22:54






  • 2





    But if you do not follow the Rule of Three, then you are very likely smurfed one way or another. You have a memory leak or sooner or later there is a double delete. Your goal as a programmer should be to design your classes to observe the Rule of zero or hide all of the management through the Rules of Three and Five from users to that they can adhere to the Rule of Zero.

    – user4581301
    Mar 7 at 22:57








1




1





If return values got destroyed before the function exited, what would be the point of return values?

– alter igel
Mar 7 at 22:47





If return values got destroyed before the function exited, what would be the point of return values?

– alter igel
Mar 7 at 22:47




1




1





But it's not being returned by reference. This is a plain old return by value. The object is being copied and it is trivially copyable so there's not much that can go wrong. Plus there is a lot of room for the compiler to eliminate the copy (See Copy Elision).

– user4581301
Mar 7 at 22:51






But it's not being returned by reference. This is a plain old return by value. The object is being copied and it is trivially copyable so there's not much that can go wrong. Plus there is a lot of room for the compiler to eliminate the copy (See Copy Elision).

– user4581301
Mar 7 at 22:51





2




2





return by reference != return by copy/value. If you were returning by reference, you would indeed have undefined behavior (UB).

– Jarod42
Mar 7 at 22:51





return by reference != return by copy/value. If you were returning by reference, you would indeed have undefined behavior (UB).

– Jarod42
Mar 7 at 22:51




2




2





@SpentDeath if your Vec3f had dynamically allocated member data, and followed the Rule of Three, then yes, it would be perfectly safe.

– alter igel
Mar 7 at 22:54





@SpentDeath if your Vec3f had dynamically allocated member data, and followed the Rule of Three, then yes, it would be perfectly safe.

– alter igel
Mar 7 at 22:54




2




2





But if you do not follow the Rule of Three, then you are very likely smurfed one way or another. You have a memory leak or sooner or later there is a double delete. Your goal as a programmer should be to design your classes to observe the Rule of zero or hide all of the management through the Rules of Three and Five from users to that they can adhere to the Rule of Zero.

– user4581301
Mar 7 at 22:57






But if you do not follow the Rule of Three, then you are very likely smurfed one way or another. You have a memory leak or sooner or later there is a double delete. Your goal as a programmer should be to design your classes to observe the Rule of zero or hide all of the management through the Rules of Three and Five from users to that they can adhere to the Rule of Zero.

– user4581301
Mar 7 at 22:57













4 Answers
4






active

oldest

votes


















1














You can look in the following example:



Vec3f Vec3f::operator*(float scale) const 
return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);


Vec3f a(1,2,3);
Vec3f b;
b = a * 2;


In general the following will happen:



  1. the operator overload implementation will construct a new instance of the Ve3f with the new arguments, representing multiplication.


  2. the return procedure will call a default copy constructor of b with the constructed object in the argument. The copy-constructor will copy fields from its argument to the instance of 'b'.


You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides.



Vec3f(const Ver3f &src)...


So, as a result you will get a new objects with all fields copied from the one created at the return statement. This is the return by value as defined in c++ for objects.



The result would be different if you returned the object by a pointer or a reference. It will cause a memory corruption.






share|improve this answer























  • You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides -- For the OP's case, the default versions of the copy constructor, assignment operator, and destructor are perfectly fine, since the only member is an array of 3 float's. Writing versions of these functions when there is no need to can lead to bugs or code that may not be optimized.

    – PaulMcKenzie
    Mar 8 at 4:13


















3














Vec3f Vec3f::operator*(float scale) const 
return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);



This uses return by value, so what is returned is the value of the class instance created by that line, not the instance itself.



This is fundamentally no different from return 1;. The value one is returned, not any particular instance or class member that contains that value. As with pretty much everything else, it's the implementation's responsibility to figure out how to accomplish what the code asks for -- in this case, ensuring that some instance exists to hold the returned value with an appropriate lifetime.






share|improve this answer
































    0














    That's the binary multiplication operator, and it's returning a copy of the data in the Vec3f instance, multiplied by float scale, into an rvalue for use by the rest of an expression.



    How that works is already answered in What are rvalues, lvalues, xvalues, glvalues, and prvalues?



    Also see https://en.cppreference.com/w/cpp/language/operator_arithmetic






    share|improve this answer




















    • 1





      By dereference operator, do you mean the unary operator*? OP's function clearly uses a float scale argument, which makes this the infix operator*. Also, I really don't think value categories shed any light on how return values work with the stack.

      – alter igel
      Mar 7 at 22:49











    • If you consider a duplicate, vote to close as it.

      – Jarod42
      Mar 7 at 22:50











    • Oh, interesting. You're right, I missed that. I'll change the operator mentioned. That said, it does return an rvalue, and understanding how return values work is still best covered by the other question, and is probably a useful read for OP. I did mark this as a duplicate.

      – Tzalumen
      Mar 7 at 22:53



















    -1














    So, every cpu has it's own calling convention. For more detailed info look into this and this



    Basically, the return value, or the address to the return value is copied to the a register like R0 in ARM and EAX in x86 so the caller of the function can access it.






    share|improve this answer























    • Whatever calling convention is being used is an implementation detail of the compiler. That's beyond the scope of the rules of the C++ language and has nothing to do with what a program means in terms of the language.

      – alter igel
      Mar 7 at 23:00











    • even if the code is in C++, the question is general and about heap and stack. they're generally wondering how values are returned and told them how.

      – Mohammad
      Mar 7 at 23:05











    • Then can you explain how the calling convention distinguishes returning by value versus returning by reference in C++, and what the calling convention does to ensure the existence of the returned object?

      – alter igel
      Mar 7 at 23:12












    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%2f55053963%2fconfusion-on-operator-overloading-and-heap-vs-stack%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    You can look in the following example:



    Vec3f Vec3f::operator*(float scale) const 
    return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);


    Vec3f a(1,2,3);
    Vec3f b;
    b = a * 2;


    In general the following will happen:



    1. the operator overload implementation will construct a new instance of the Ve3f with the new arguments, representing multiplication.


    2. the return procedure will call a default copy constructor of b with the constructed object in the argument. The copy-constructor will copy fields from its argument to the instance of 'b'.


    You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides.



    Vec3f(const Ver3f &src)...


    So, as a result you will get a new objects with all fields copied from the one created at the return statement. This is the return by value as defined in c++ for objects.



    The result would be different if you returned the object by a pointer or a reference. It will cause a memory corruption.






    share|improve this answer























    • You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides -- For the OP's case, the default versions of the copy constructor, assignment operator, and destructor are perfectly fine, since the only member is an array of 3 float's. Writing versions of these functions when there is no need to can lead to bugs or code that may not be optimized.

      – PaulMcKenzie
      Mar 8 at 4:13















    1














    You can look in the following example:



    Vec3f Vec3f::operator*(float scale) const 
    return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);


    Vec3f a(1,2,3);
    Vec3f b;
    b = a * 2;


    In general the following will happen:



    1. the operator overload implementation will construct a new instance of the Ve3f with the new arguments, representing multiplication.


    2. the return procedure will call a default copy constructor of b with the constructed object in the argument. The copy-constructor will copy fields from its argument to the instance of 'b'.


    You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides.



    Vec3f(const Ver3f &src)...


    So, as a result you will get a new objects with all fields copied from the one created at the return statement. This is the return by value as defined in c++ for objects.



    The result would be different if you returned the object by a pointer or a reference. It will cause a memory corruption.






    share|improve this answer























    • You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides -- For the OP's case, the default versions of the copy constructor, assignment operator, and destructor are perfectly fine, since the only member is an array of 3 float's. Writing versions of these functions when there is no need to can lead to bugs or code that may not be optimized.

      – PaulMcKenzie
      Mar 8 at 4:13













    1












    1








    1







    You can look in the following example:



    Vec3f Vec3f::operator*(float scale) const 
    return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);


    Vec3f a(1,2,3);
    Vec3f b;
    b = a * 2;


    In general the following will happen:



    1. the operator overload implementation will construct a new instance of the Ve3f with the new arguments, representing multiplication.


    2. the return procedure will call a default copy constructor of b with the constructed object in the argument. The copy-constructor will copy fields from its argument to the instance of 'b'.


    You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides.



    Vec3f(const Ver3f &src)...


    So, as a result you will get a new objects with all fields copied from the one created at the return statement. This is the return by value as defined in c++ for objects.



    The result would be different if you returned the object by a pointer or a reference. It will cause a memory corruption.






    share|improve this answer













    You can look in the following example:



    Vec3f Vec3f::operator*(float scale) const 
    return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);


    Vec3f a(1,2,3);
    Vec3f b;
    b = a * 2;


    In general the following will happen:



    1. the operator overload implementation will construct a new instance of the Ve3f with the new arguments, representing multiplication.


    2. the return procedure will call a default copy constructor of b with the constructed object in the argument. The copy-constructor will copy fields from its argument to the instance of 'b'.


    You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides.



    Vec3f(const Ver3f &src)...


    So, as a result you will get a new objects with all fields copied from the one created at the return statement. This is the return by value as defined in c++ for objects.



    The result would be different if you returned the object by a pointer or a reference. It will cause a memory corruption.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Mar 8 at 3:26









    SergeSerge

    4,12221016




    4,12221016












    • You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides -- For the OP's case, the default versions of the copy constructor, assignment operator, and destructor are perfectly fine, since the only member is an array of 3 float's. Writing versions of these functions when there is no need to can lead to bugs or code that may not be optimized.

      – PaulMcKenzie
      Mar 8 at 4:13

















    • You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides -- For the OP's case, the default versions of the copy constructor, assignment operator, and destructor are perfectly fine, since the only member is an array of 3 float's. Writing versions of these functions when there is no need to can lead to bugs or code that may not be optimized.

      – PaulMcKenzie
      Mar 8 at 4:13
















    You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides -- For the OP's case, the default versions of the copy constructor, assignment operator, and destructor are perfectly fine, since the only member is an array of 3 float's. Writing versions of these functions when there is no need to can lead to bugs or code that may not be optimized.

    – PaulMcKenzie
    Mar 8 at 4:13





    You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides -- For the OP's case, the default versions of the copy constructor, assignment operator, and destructor are perfectly fine, since the only member is an array of 3 float's. Writing versions of these functions when there is no need to can lead to bugs or code that may not be optimized.

    – PaulMcKenzie
    Mar 8 at 4:13













    3














    Vec3f Vec3f::operator*(float scale) const 
    return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);



    This uses return by value, so what is returned is the value of the class instance created by that line, not the instance itself.



    This is fundamentally no different from return 1;. The value one is returned, not any particular instance or class member that contains that value. As with pretty much everything else, it's the implementation's responsibility to figure out how to accomplish what the code asks for -- in this case, ensuring that some instance exists to hold the returned value with an appropriate lifetime.






    share|improve this answer





























      3














      Vec3f Vec3f::operator*(float scale) const 
      return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);



      This uses return by value, so what is returned is the value of the class instance created by that line, not the instance itself.



      This is fundamentally no different from return 1;. The value one is returned, not any particular instance or class member that contains that value. As with pretty much everything else, it's the implementation's responsibility to figure out how to accomplish what the code asks for -- in this case, ensuring that some instance exists to hold the returned value with an appropriate lifetime.






      share|improve this answer



























        3












        3








        3







        Vec3f Vec3f::operator*(float scale) const 
        return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);



        This uses return by value, so what is returned is the value of the class instance created by that line, not the instance itself.



        This is fundamentally no different from return 1;. The value one is returned, not any particular instance or class member that contains that value. As with pretty much everything else, it's the implementation's responsibility to figure out how to accomplish what the code asks for -- in this case, ensuring that some instance exists to hold the returned value with an appropriate lifetime.






        share|improve this answer















        Vec3f Vec3f::operator*(float scale) const 
        return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);



        This uses return by value, so what is returned is the value of the class instance created by that line, not the instance itself.



        This is fundamentally no different from return 1;. The value one is returned, not any particular instance or class member that contains that value. As with pretty much everything else, it's the implementation's responsibility to figure out how to accomplish what the code asks for -- in this case, ensuring that some instance exists to hold the returned value with an appropriate lifetime.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 7 at 23:11

























        answered Mar 7 at 22:54









        David SchwartzDavid Schwartz

        139k14145230




        139k14145230





















            0














            That's the binary multiplication operator, and it's returning a copy of the data in the Vec3f instance, multiplied by float scale, into an rvalue for use by the rest of an expression.



            How that works is already answered in What are rvalues, lvalues, xvalues, glvalues, and prvalues?



            Also see https://en.cppreference.com/w/cpp/language/operator_arithmetic






            share|improve this answer




















            • 1





              By dereference operator, do you mean the unary operator*? OP's function clearly uses a float scale argument, which makes this the infix operator*. Also, I really don't think value categories shed any light on how return values work with the stack.

              – alter igel
              Mar 7 at 22:49











            • If you consider a duplicate, vote to close as it.

              – Jarod42
              Mar 7 at 22:50











            • Oh, interesting. You're right, I missed that. I'll change the operator mentioned. That said, it does return an rvalue, and understanding how return values work is still best covered by the other question, and is probably a useful read for OP. I did mark this as a duplicate.

              – Tzalumen
              Mar 7 at 22:53
















            0














            That's the binary multiplication operator, and it's returning a copy of the data in the Vec3f instance, multiplied by float scale, into an rvalue for use by the rest of an expression.



            How that works is already answered in What are rvalues, lvalues, xvalues, glvalues, and prvalues?



            Also see https://en.cppreference.com/w/cpp/language/operator_arithmetic






            share|improve this answer




















            • 1





              By dereference operator, do you mean the unary operator*? OP's function clearly uses a float scale argument, which makes this the infix operator*. Also, I really don't think value categories shed any light on how return values work with the stack.

              – alter igel
              Mar 7 at 22:49











            • If you consider a duplicate, vote to close as it.

              – Jarod42
              Mar 7 at 22:50











            • Oh, interesting. You're right, I missed that. I'll change the operator mentioned. That said, it does return an rvalue, and understanding how return values work is still best covered by the other question, and is probably a useful read for OP. I did mark this as a duplicate.

              – Tzalumen
              Mar 7 at 22:53














            0












            0








            0







            That's the binary multiplication operator, and it's returning a copy of the data in the Vec3f instance, multiplied by float scale, into an rvalue for use by the rest of an expression.



            How that works is already answered in What are rvalues, lvalues, xvalues, glvalues, and prvalues?



            Also see https://en.cppreference.com/w/cpp/language/operator_arithmetic






            share|improve this answer















            That's the binary multiplication operator, and it's returning a copy of the data in the Vec3f instance, multiplied by float scale, into an rvalue for use by the rest of an expression.



            How that works is already answered in What are rvalues, lvalues, xvalues, glvalues, and prvalues?



            Also see https://en.cppreference.com/w/cpp/language/operator_arithmetic







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 7 at 22:57

























            answered Mar 7 at 22:47









            TzalumenTzalumen

            486212




            486212







            • 1





              By dereference operator, do you mean the unary operator*? OP's function clearly uses a float scale argument, which makes this the infix operator*. Also, I really don't think value categories shed any light on how return values work with the stack.

              – alter igel
              Mar 7 at 22:49











            • If you consider a duplicate, vote to close as it.

              – Jarod42
              Mar 7 at 22:50











            • Oh, interesting. You're right, I missed that. I'll change the operator mentioned. That said, it does return an rvalue, and understanding how return values work is still best covered by the other question, and is probably a useful read for OP. I did mark this as a duplicate.

              – Tzalumen
              Mar 7 at 22:53













            • 1





              By dereference operator, do you mean the unary operator*? OP's function clearly uses a float scale argument, which makes this the infix operator*. Also, I really don't think value categories shed any light on how return values work with the stack.

              – alter igel
              Mar 7 at 22:49











            • If you consider a duplicate, vote to close as it.

              – Jarod42
              Mar 7 at 22:50











            • Oh, interesting. You're right, I missed that. I'll change the operator mentioned. That said, it does return an rvalue, and understanding how return values work is still best covered by the other question, and is probably a useful read for OP. I did mark this as a duplicate.

              – Tzalumen
              Mar 7 at 22:53








            1




            1





            By dereference operator, do you mean the unary operator*? OP's function clearly uses a float scale argument, which makes this the infix operator*. Also, I really don't think value categories shed any light on how return values work with the stack.

            – alter igel
            Mar 7 at 22:49





            By dereference operator, do you mean the unary operator*? OP's function clearly uses a float scale argument, which makes this the infix operator*. Also, I really don't think value categories shed any light on how return values work with the stack.

            – alter igel
            Mar 7 at 22:49













            If you consider a duplicate, vote to close as it.

            – Jarod42
            Mar 7 at 22:50





            If you consider a duplicate, vote to close as it.

            – Jarod42
            Mar 7 at 22:50













            Oh, interesting. You're right, I missed that. I'll change the operator mentioned. That said, it does return an rvalue, and understanding how return values work is still best covered by the other question, and is probably a useful read for OP. I did mark this as a duplicate.

            – Tzalumen
            Mar 7 at 22:53






            Oh, interesting. You're right, I missed that. I'll change the operator mentioned. That said, it does return an rvalue, and understanding how return values work is still best covered by the other question, and is probably a useful read for OP. I did mark this as a duplicate.

            – Tzalumen
            Mar 7 at 22:53












            -1














            So, every cpu has it's own calling convention. For more detailed info look into this and this



            Basically, the return value, or the address to the return value is copied to the a register like R0 in ARM and EAX in x86 so the caller of the function can access it.






            share|improve this answer























            • Whatever calling convention is being used is an implementation detail of the compiler. That's beyond the scope of the rules of the C++ language and has nothing to do with what a program means in terms of the language.

              – alter igel
              Mar 7 at 23:00











            • even if the code is in C++, the question is general and about heap and stack. they're generally wondering how values are returned and told them how.

              – Mohammad
              Mar 7 at 23:05











            • Then can you explain how the calling convention distinguishes returning by value versus returning by reference in C++, and what the calling convention does to ensure the existence of the returned object?

              – alter igel
              Mar 7 at 23:12
















            -1














            So, every cpu has it's own calling convention. For more detailed info look into this and this



            Basically, the return value, or the address to the return value is copied to the a register like R0 in ARM and EAX in x86 so the caller of the function can access it.






            share|improve this answer























            • Whatever calling convention is being used is an implementation detail of the compiler. That's beyond the scope of the rules of the C++ language and has nothing to do with what a program means in terms of the language.

              – alter igel
              Mar 7 at 23:00











            • even if the code is in C++, the question is general and about heap and stack. they're generally wondering how values are returned and told them how.

              – Mohammad
              Mar 7 at 23:05











            • Then can you explain how the calling convention distinguishes returning by value versus returning by reference in C++, and what the calling convention does to ensure the existence of the returned object?

              – alter igel
              Mar 7 at 23:12














            -1












            -1








            -1







            So, every cpu has it's own calling convention. For more detailed info look into this and this



            Basically, the return value, or the address to the return value is copied to the a register like R0 in ARM and EAX in x86 so the caller of the function can access it.






            share|improve this answer













            So, every cpu has it's own calling convention. For more detailed info look into this and this



            Basically, the return value, or the address to the return value is copied to the a register like R0 in ARM and EAX in x86 so the caller of the function can access it.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 7 at 22:54









            MohammadMohammad

            248




            248












            • Whatever calling convention is being used is an implementation detail of the compiler. That's beyond the scope of the rules of the C++ language and has nothing to do with what a program means in terms of the language.

              – alter igel
              Mar 7 at 23:00











            • even if the code is in C++, the question is general and about heap and stack. they're generally wondering how values are returned and told them how.

              – Mohammad
              Mar 7 at 23:05











            • Then can you explain how the calling convention distinguishes returning by value versus returning by reference in C++, and what the calling convention does to ensure the existence of the returned object?

              – alter igel
              Mar 7 at 23:12


















            • Whatever calling convention is being used is an implementation detail of the compiler. That's beyond the scope of the rules of the C++ language and has nothing to do with what a program means in terms of the language.

              – alter igel
              Mar 7 at 23:00











            • even if the code is in C++, the question is general and about heap and stack. they're generally wondering how values are returned and told them how.

              – Mohammad
              Mar 7 at 23:05











            • Then can you explain how the calling convention distinguishes returning by value versus returning by reference in C++, and what the calling convention does to ensure the existence of the returned object?

              – alter igel
              Mar 7 at 23:12

















            Whatever calling convention is being used is an implementation detail of the compiler. That's beyond the scope of the rules of the C++ language and has nothing to do with what a program means in terms of the language.

            – alter igel
            Mar 7 at 23:00





            Whatever calling convention is being used is an implementation detail of the compiler. That's beyond the scope of the rules of the C++ language and has nothing to do with what a program means in terms of the language.

            – alter igel
            Mar 7 at 23:00













            even if the code is in C++, the question is general and about heap and stack. they're generally wondering how values are returned and told them how.

            – Mohammad
            Mar 7 at 23:05





            even if the code is in C++, the question is general and about heap and stack. they're generally wondering how values are returned and told them how.

            – Mohammad
            Mar 7 at 23:05













            Then can you explain how the calling convention distinguishes returning by value versus returning by reference in C++, and what the calling convention does to ensure the existence of the returned object?

            – alter igel
            Mar 7 at 23:12






            Then can you explain how the calling convention distinguishes returning by value versus returning by reference in C++, and what the calling convention does to ensure the existence of the returned object?

            – alter igel
            Mar 7 at 23:12


















            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%2f55053963%2fconfusion-on-operator-overloading-and-heap-vs-stack%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

            1928 у кіно

            Захаров Федір Захарович

            Ель Греко