Passing temporary variable by value

This is a discussion on Passing temporary variable by value within the C++ Programming forums, part of the General Programming Boards category; Code: #include <iostream> using namespace std; struct X { int i; X(int j = 0): i(j){cout << "constructor\n";} X(const X& ...

  1. #1
    DL1
    DL1 is offline
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99

    Passing temporary variable by value

    Code:
    #include <iostream>
    using namespace std;
    
    struct X
    {
        int i;
        X(int j = 0): i(j){cout << "constructor\n";}
        X(const X& x): i(x.i){cout << "copy constructor\n";}
        ~X(){cout << "destructor\n";}
        X& operator=(const X& x);
    };
    
    X& X::operator=(const X& x)
    {
        cout << "assignment operator\n";
        if (this != &x) i = x.i;
        return *this;
    }
    
    X y(int i)
    {
        cout << "in y()\n";
        return X(i);//<-----------------This
    }
    
    //const X& func(const X& x)
    const X& func(X x)//<------------ends up here
    {
        cout << "in func()\n";
        return x;
    }
    
    int main()
    {
        func(y(99));
        return 0;
    }
    When I run the above program, the copy constructor is not called when the temporary variable from y() is passed by value to func(). I thought the whole point of passing by value is that a new object is made that is initialised with the value being passed. Does that only apply when the function argument is a global or static object?

    Can anyone enlighten me as to why that should be the case?

    Thanks.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The compiler can sometimes optimize away the constructor calls, that's the only thing I can think of.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,255
    The compiler is allowed to optimize out that temporary copy.

    Also keep in mind that func() is returning a reference to a local variable which is bad news. Note that the compiler would not be able to perform this optimization if you changed your code to:

    Code:
    int main()
    {
        X x(99);
        func(x);
        return 0;
    }

  4. #4
    DL1
    DL1 is offline
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    Thanks.

    Would the
    Code:
    const X& func(const X& x
    ) version be safe?

  5. #5
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,255
    It depends on how the function is called.

    Code:
    X& x = func(X());
    would not be safe.
    Code:
    X& x = funct(existingX);
    would be safe as long as existingX stayed in scope.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,256
    Quote Originally Posted by bithub
    It depends on how the function is called.

    Code:
    X& x = func(X());
    would not be safe.
    The X& should be changed to const X&. Once that is done, are you sure that that would not be safe? Copy constructor elision aside, I thought that that would result in the reference parameter for func() being bound to a copy of the temporary returned from the constructor invocation. The temporary to which reference returned from func() is bound would then be copied to another temporary to which x would then be bound. The lifetime of this temporary persists for the lifetime of the reference x.

    Quote Originally Posted by bithub
    X& x = funct(existingX);[/code]
    would be safe as long as existingX stayed in scope.
    I think that existingX must remain in scope, since there is no way for the reference x to go out of scope after existingX goes out of scope.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,255
    The X& should be changed to const X&. Once that is done, are you sure that that would not be safe?
    You're right, I completely missed the const in his prototype.

    I think that existingX must remain in scope, since there is no way for the reference x to go out of scope after existingX goes out of scope.
    I used the term scope to mean the lifetime of the passed object. What i meant was for him to watch out for situations similar to:
    Code:
    existingX = new X();
    X& x = funct(*existingX);
    delete existingX;
    // use x here...
    which would obviously cause problems.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 01-29-2006, 06:57 PM
  2. Make a variable available everywhere without passing?
    By Austin in forum C++ Programming
    Replies: 9
    Last Post: 03-03-2005, 11:38 AM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. About classes and HINSTANCE variable to Main
    By conright in forum Windows Programming
    Replies: 2
    Last Post: 01-01-2003, 08:00 PM
  5. creating class, and linking files
    By JCK in forum C++ Programming
    Replies: 12
    Last Post: 12-08-2002, 02:45 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21