Please explain this unexpected behavior (regarding return-by-value)

Discussion in 'C++' started by duffdevice@gmail.com, Nov 10, 2006.

  1. Guest

    Hi, I came across this unexpected behavior while working on something
    else. I am attempting to return a custom type by value from a global
    function. I have a trace in the custom class's copy constructor, and I
    expected this code to tell me that the custom copy constructor had been
    called twice. Instead, it's only called once and the program executes
    correctly.

    Is this an optimization related to my compiler (g++ v4.0.1) or is this
    specified by the standard? Can somebody clear this behavior up for me?

    Thanks in advance!

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // start example source
    #include <string>
    #include <iostream>
    using std::string;
    using std::cout;
    using std::endl;

    class Test
    {
    string member_;

    public:
    Test(const string& s) : member_(s) { }
    Test(const Test& copy) : member_(copy.member_) {
    cout << "copy" << endl;
    }

    void out() { cout << member_ << endl; }

    };

    Test test_by_value(const Test& in)
    {

    Test temp(in); // expect a copy here while constructing temp
    return temp; // also expect a copy here to return the value of
    temp, which currently exists on the stack
    }

    int main()
    {
    Test t("hello");
    Test v = test_by_value(t);
    v.out();

    return 0;
    }


    /*
    expected output:
    copy
    copy
    hello


    actual output:
    copy
    hello

    how is the copied value being returned from test_by_value() without a
    second copy (since temp is a stack var)?
    */


    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    , Nov 10, 2006
    #1
    1. Advertising

  2. * :
    > Hi, I came across this unexpected behavior while working on something
    > else. I am attempting to return a custom type by value from a global
    > function. I have a trace in the custom class's copy constructor, and I
    > expected this code to tell me that the custom copy constructor had been
    > called twice. Instead, it's only called once and the program executes
    > correctly.


    Copy constructor calls are allowed to be optimized away -- in many
    situations -- regardless of possible side-effects in the copy constructor.

    So generally you can't "expect" any specific number of calls.

    For your specific example, look up RVO and NRVO.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Nov 10, 2006
    #2
    1. Advertising

  3. Salt_Peter Guest

    wrote:
    > Hi, I came across this unexpected behavior while working on something
    > else. I am attempting to return a custom type by value from a global
    > function. I have a trace in the custom class's copy constructor, and I
    > expected this code to tell me that the custom copy constructor had been
    > called twice. Instead, it's only called once and the program executes
    > correctly.
    >
    > Is this an optimization related to my compiler (g++ v4.0.1) or is this
    > specified by the standard? Can somebody clear this behavior up for me?
    >
    > Thanks in advance!
    >
    > //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    > // start example source
    > #include <string>
    > #include <iostream>
    > using std::string;
    > using std::cout;
    > using std::endl;
    >
    > class Test
    > {
    > string member_;
    >
    > public:
    > Test(const string& s) : member_(s) { }
    > Test(const Test& copy) : member_(copy.member_) {
    > cout << "copy" << endl;
    > }
    >
    > void out() { cout << member_ << endl; }
    >
    > };
    >
    > Test test_by_value(const Test& in)
    > {
    >
    > Test temp(in); // expect a copy here while constructing temp
    > return temp; // also expect a copy here to return the value of
    > temp, which currently exists on the stack
    > }
    >
    > int main()
    > {
    > Test t("hello");
    > Test v = test_by_value(t);
    > v.out();
    >
    > return 0;
    > }
    >
    >
    > /*
    > expected output:
    > copy
    > copy
    > hello
    >
    >
    > actual output:
    > copy
    > hello
    >
    > how is the copied value being returned from test_by_value() without a
    > second copy (since temp is a stack var)?
    > */



    Because the following:

    Test v = test_by_value(t);

    is usually optimized to:

    Test v(test_by_value(t));

    which is completely legal, btw.

    Note the same happens with a primitive:
    int x(99);
    int n = x; // is actually a copy
    Salt_Peter, Nov 10, 2006
    #3
  4. *PaN!* Guest

    *PaN!*, Nov 10, 2006
    #4
  5. On 9 Nov 2006 20:58:52 -0800, wrote:
    >Is this an optimization related to my compiler (g++ v4.0.1) or is this
    >specified by the standard? Can somebody clear this behavior up for me?


    This 'optimization' (the (N)RVO hack) is compiler specific. IIRC, you
    can turn it off with a compiler switch for g++.

    Best wishes,
    Roland Pibinger
    Roland Pibinger, Nov 10, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?cmdyYW5kaWRpZXI=?=

    Please explain strange viewstate behavior...

    =?Utf-8?B?cmdyYW5kaWRpZXI=?=, Oct 26, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    427
    Eliyahu Goldin
    Oct 27, 2005
  2. REH
    Replies:
    25
    Views:
    828
    Victor Bazarov
    Mar 29, 2005
  3. Mike Kent
    Replies:
    9
    Views:
    333
    Mike Kent
    Jan 24, 2008
  4. Juan Romero

    unexpected behavior in Datagrid paging : PLEASE HELP >: (

    Juan Romero, Sep 10, 2003, in forum: ASP .Net Datagrid Control
    Replies:
    1
    Views:
    121
    Alvin Bruney
    Sep 11, 2003
  5. BKDotCom
    Replies:
    3
    Views:
    78
    Jonas Raoni
    Dec 22, 2005
Loading...

Share This Page