How to "return an object" in C++? - c++

I know the title sounds familiar as there are many similar questions, but I'm asking for a different aspect of the problem (I know the difference between having things on the stack and putting them on the heap).
In Java I can always return references to "local" objects
public Thing calculateThing() {
Thing thing = new Thing();
// do calculations and modify thing
return thing;
}
In C++, to do something similar I have 2 options
(1) I can use references whenever I need to "return" an object
void calculateThing(Thing& thing) {
// do calculations and modify thing
}
Then use it like this
Thing thing;
calculateThing(thing);
(2) Or I can return a pointer to a dynamically allocated object
Thing* calculateThing() {
Thing* thing(new Thing());
// do calculations and modify thing
return thing;
}
Then use it like this
Thing* thing = calculateThing();
delete thing;
Using the first approach I won't have to free memory manually, but to me it makes the code difficult to read. The problem with the second approach is, I'll have to remember to delete thing;, which doesn't look quite nice. I don't want to return a copied value because it's inefficient (I think), so here come the questions
Is there a third solution (that doesn't require copying the value)?
Is there any problem if I stick to the first solution?
When and why should I use the second solution?

I don't want to return a copied value because it's inefficient
Prove it.
Look up RVO and NRVO, and in C++0x move-semantics. In most cases in C++03, an out parameter is just a good way to make your code ugly, and in C++0x you'd actually be hurting yourself by using an out parameter.
Just write clean code, return by value. If performance is a problem, profile it (stop guessing), and find what you can do to fix it. It likely won't be returning things from functions.
That said, if you're dead set on writing like that, you'd probably want to do the out parameter. It avoids dynamic memory allocation, which is safer and generally faster. It does require you have some way to construct the object prior to calling the function, which doesn't always make sense for all objects.
If you want to use dynamic allocation, the least that can be done is put it in a smart pointer. (This should be done all the time anyway) Then you don't worry about deleting anything, things are exception-safe, etc. The only problem is it's likely slower than returning by value anyway!

Just create the object and return it
Thing calculateThing() {
Thing thing;
// do calculations and modify thing
return thing;
}
I think you'll do yourself a favor if you forget about optimization and just write readable code (you'll need to run a profiler later - but don't pre-optimize).

Just return a object like this:
Thing calculateThing()
{
Thing thing();
// do calculations and modify thing
return thing;
}
This will invoke the copy constructor on Things, so you might want to do your own implementation of that. Like this:
Thing(const Thing& aThing) {}
This might perform a little slower, but it might not be an issue at all.
Update
The compiler will probably optimize the call to the copy constructor, so there will be no extra overhead. (Like dreamlax pointed out in the comment).

Did you try to use smart pointers (if Thing is really big and heavy object), like shared_ptr:
std::shared_ptr calculateThing()
{
std::shared_ptr<Thing> thing(new Thing);
// .. some calculations
return thing;
}
// ...
{
std::shared_ptr<Thing> thing = calculateThing();
// working with thing
// shared_ptr frees thing
}

One quick way to determine if a copy constructor is being called is to add logging to your class's copy constructor:
MyClass::MyClass(const MyClass &other)
{
std::cout << "Copy constructor was called" << std::endl;
}
MyClass someFunction()
{
MyClass dummy;
return dummy;
}
Call someFunction; the number of "Copy constructor was called" lines that you will get will vary between 0, 1, and 2. If you get none, then your compiler has optimised the return value out (which it is allowed to do). If you get don't get 0, and your copy constructor is ridiculously expensive, then search for alternative ways to return instances from your functions.

Firstly you have an error in the code, you mean to have Thing *thing(new Thing());, and only return thing;.
Use shared_ptr<Thing>. Deref it as tho it was a pointer. It will be deleted for you when the last reference to the Thing contained goes out of scope.
The first solution is very common in naive libraries. It has some performance, and syntactical overhead, avoid it if possible
Use the second solution only if you can guarantee no exceptions will be thrown, or when performance is absolutely critical (you will be interfacing with C or assembly before this even becomes relevant).

I don't want to return a copied value because it's inefficient
This may not be true. Compilers can do optimisation to prevent this copying.
For example, GCC does this optimisation. In the following program, neither move constructor nor copy constructor are called, since no copying or moving is done. Also, notice the address of c. Even though the object c is instantiated inside the function f(), c resides in the stack frame of main().
class C {
public:
int c = 5;
C() {}
C(const C& c) {
cout << "Copy constructor " << endl;
}
C(const C&& c) noexcept {
cout << "Move Constructor" << endl;
}
};
C f() {
int beforeC;
C c;
int afterC;
cout << &beforeC << endl; //0x7ffee02f26ac
cout << &c << endl; //0x7ffee02f2710 (notice: even though c is instantiated inside f(), c resides in the stack frame of main()
cout << &afterC << endl; //0x7ffee02f26a8
return c;
}
C g() {
C c = f(); ///neither copy constructor nor move constructor of C are called, since none is done
cout << &c << endl; //0x7ffee02f2710
return c;
}
int main() {
int beforeC;
C c = g(); ///neither copy constructor nor move constructor of C are called, since none is done
int afterC;
cout << &beforeC << endl; //0x7ffee02f2718
cout << &c << endl; //0x7ffee02f2710 (notice:even though c is returned from f,it resides in the stack frame of main)
cout << &afterC << endl; //0x7ffee02f270c
return 0;
}

I'm sure a C++ expert will come along with a better answer, but personally I like the second approach. Using smart pointers helps with the problem of forgetting to delete and as you say, it looks cleaner than having to create an object before hand (and still having to delete it if you want to allocate it on the heap).

Related

C++ difference between passing argument from a function call or passing argument from variable

Whats the difference between this:
function1(function2());
And this:
var1 = function2();
function1(var1);
In terms of efficiency or whatever, what is the best option?
Before C++11 there is no big difference. Since move semantics were introduced the difference can be substantial. For example when a function needs to make a copy of its parameter it can have two overloads: one that actually does make a copy and another one that can move when the parameter is a temporary:
#include <iostream>
struct bar {};
bar b() { return {};}
struct foo {
bar b;
void set(const bar& in) {
std::cout << "copy \n";
b = in;
}
void set(bar&& in){
std::cout << "no need to copy, can move\n";
b = std::move(in);
}
};
int main() {
foo f;
bar b1;
f.set(b1);
f.set(b());
}
bar in this example is just a lightweight class, but when it is cheap to move but expensive to copy then f.set(b1) is less efficient than f.set(b()). The caller could f.set(std::move(b1)), but it is more clear to call f.set(b()) rather than having a moved from object hanging around.
However, already before C++11, the question you should actually ask is: Does it make sense to give a name to the result of calling function2? Do you need the result only to call function1 or do you need it also elsewhere? And this can be answered independently of whether you are writing ancient C++ or whether move semantics are involved. In short: Write code to be clear and readable. Concerns about efficieny are for a later stage, when you have correct and working code that you can measure and profile.

C++ destruction order: Calling a field destructor before the class destructor

Is there any way to call a field destructor before the class destructor?
Suppose I have 2 classes Small and Big, and Big contains an instance of Small as its field as such:
class Small
{
public:
~Small() {std::cout << "Small destructor" << std::endl;}
};
class Big
{
public:
~Big() {std::cout << "Big destructor" << std::endl;}
private:
Small small;
};
int main()
{
Big big;
}
This, of course, calls the big destructor before the small destructor:
Big destructor
Small destructor
I need the Small destructor to be called before the Big destructor since it does some cleanup necessary for the Big destructor.
I could:
call the small.~Small() destructor explicitly. -> This, however, calls the Small destructor twice: once explicitly, and once after the Big destructor has been executed.
have a Small* as the field and call delete small; in the Big destructor
I am aware that I can have a function in the Small class that does the cleanup and call it in the Big destructor, but I was wondering if there was a way to inverse the destructor order.
Is there any better way to do this?
call the small.~Small() destructor explicitly. -> This, however, calls the small destructor twice: once explicitly, and once after the big destructor has been executed.
Well, I don't know why you want to keep on with this flawing design, but you can solve the problem described in your first bullet using placement new.
It follows a minimal, working example:
#include <iostream>
struct Small {
~Small() {std::cout << "Small destructor" << std::endl;}
};
struct Big {
Big() { ::new (storage) Small; }
~Big() {
reinterpret_cast<Small *>(storage)->~Small();
std::cout << "Big destructor" << std::endl;
}
Small & small() {
return *reinterpret_cast<Small *>(storage);
}
private:
unsigned char storage[sizeof(Small)];
};
int main() {
Big big;
}
You don't have anymore a variable of type Small, but with something like the small member function in the example you can easily work around it.
The idea is that you reserve enough space to construct in-place a Small and then you can invoke its destructor explicitly as you did. It won't be called twice, for all what the Big class has to release is an array of unsigned chars.
Moreover, you won't store your Small into the dynamic storage directly, for actually you are using a data member of your Big to create it in.
That being said, I'd suggest you to allocate it on the dynamic storage unless you have a good reason to do otherwise. Use a std::unique_ptr and reset it at the beginning of the destructor of Big. Your Small will go away before the body of the destructor is actually executed as expected and also in this case the destructor won't be called twice.
EDIT
As suggested in the comments, std::optional can be another viable solution instead of std::unique_ptr. Keep in mind that std::optional is part of the C++17, so if you can use it mostly depends on what's the revision of the standard to which you must adhere.
Without knowing why you want to do this, my only suggestion is to break up Big into the parts that need to be destroyed after Small from the rest and then use composition to include that inside Big. Then you have control over the order of destruction:
class Small
{
public:
~Small() {std::cout << "Small destructor" << std::endl;}
};
class BigImpl
{
public:
~BigImpl() { std::cout << "Big destructor" << std::endl; }
};
class Big
{
private:
BigImpl bigimpl;
Small small;
};
The order of destructor calls cannot be changed. The proper way to design this is that Small performs its own cleanup.
If you cannot change Small then you could make a class SmallWrapper that contains a Small and also can perform the required cleanup.
The standard containers std::optional or std::unique_ptr or std::shared_ptr might suffice for this purpose.

Should we return pointer to a vector from a function? [duplicate]

I know the title sounds familiar as there are many similar questions, but I'm asking for a different aspect of the problem (I know the difference between having things on the stack and putting them on the heap).
In Java I can always return references to "local" objects
public Thing calculateThing() {
Thing thing = new Thing();
// do calculations and modify thing
return thing;
}
In C++, to do something similar I have 2 options
(1) I can use references whenever I need to "return" an object
void calculateThing(Thing& thing) {
// do calculations and modify thing
}
Then use it like this
Thing thing;
calculateThing(thing);
(2) Or I can return a pointer to a dynamically allocated object
Thing* calculateThing() {
Thing* thing(new Thing());
// do calculations and modify thing
return thing;
}
Then use it like this
Thing* thing = calculateThing();
delete thing;
Using the first approach I won't have to free memory manually, but to me it makes the code difficult to read. The problem with the second approach is, I'll have to remember to delete thing;, which doesn't look quite nice. I don't want to return a copied value because it's inefficient (I think), so here come the questions
Is there a third solution (that doesn't require copying the value)?
Is there any problem if I stick to the first solution?
When and why should I use the second solution?
I don't want to return a copied value because it's inefficient
Prove it.
Look up RVO and NRVO, and in C++0x move-semantics. In most cases in C++03, an out parameter is just a good way to make your code ugly, and in C++0x you'd actually be hurting yourself by using an out parameter.
Just write clean code, return by value. If performance is a problem, profile it (stop guessing), and find what you can do to fix it. It likely won't be returning things from functions.
That said, if you're dead set on writing like that, you'd probably want to do the out parameter. It avoids dynamic memory allocation, which is safer and generally faster. It does require you have some way to construct the object prior to calling the function, which doesn't always make sense for all objects.
If you want to use dynamic allocation, the least that can be done is put it in a smart pointer. (This should be done all the time anyway) Then you don't worry about deleting anything, things are exception-safe, etc. The only problem is it's likely slower than returning by value anyway!
Just create the object and return it
Thing calculateThing() {
Thing thing;
// do calculations and modify thing
return thing;
}
I think you'll do yourself a favor if you forget about optimization and just write readable code (you'll need to run a profiler later - but don't pre-optimize).
Just return a object like this:
Thing calculateThing()
{
Thing thing();
// do calculations and modify thing
return thing;
}
This will invoke the copy constructor on Things, so you might want to do your own implementation of that. Like this:
Thing(const Thing& aThing) {}
This might perform a little slower, but it might not be an issue at all.
Update
The compiler will probably optimize the call to the copy constructor, so there will be no extra overhead. (Like dreamlax pointed out in the comment).
Did you try to use smart pointers (if Thing is really big and heavy object), like shared_ptr:
std::shared_ptr calculateThing()
{
std::shared_ptr<Thing> thing(new Thing);
// .. some calculations
return thing;
}
// ...
{
std::shared_ptr<Thing> thing = calculateThing();
// working with thing
// shared_ptr frees thing
}
One quick way to determine if a copy constructor is being called is to add logging to your class's copy constructor:
MyClass::MyClass(const MyClass &other)
{
std::cout << "Copy constructor was called" << std::endl;
}
MyClass someFunction()
{
MyClass dummy;
return dummy;
}
Call someFunction; the number of "Copy constructor was called" lines that you will get will vary between 0, 1, and 2. If you get none, then your compiler has optimised the return value out (which it is allowed to do). If you get don't get 0, and your copy constructor is ridiculously expensive, then search for alternative ways to return instances from your functions.
Firstly you have an error in the code, you mean to have Thing *thing(new Thing());, and only return thing;.
Use shared_ptr<Thing>. Deref it as tho it was a pointer. It will be deleted for you when the last reference to the Thing contained goes out of scope.
The first solution is very common in naive libraries. It has some performance, and syntactical overhead, avoid it if possible
Use the second solution only if you can guarantee no exceptions will be thrown, or when performance is absolutely critical (you will be interfacing with C or assembly before this even becomes relevant).
I don't want to return a copied value because it's inefficient
This may not be true. Compilers can do optimisation to prevent this copying.
For example, GCC does this optimisation. In the following program, neither move constructor nor copy constructor are called, since no copying or moving is done. Also, notice the address of c. Even though the object c is instantiated inside the function f(), c resides in the stack frame of main().
class C {
public:
int c = 5;
C() {}
C(const C& c) {
cout << "Copy constructor " << endl;
}
C(const C&& c) noexcept {
cout << "Move Constructor" << endl;
}
};
C f() {
int beforeC;
C c;
int afterC;
cout << &beforeC << endl; //0x7ffee02f26ac
cout << &c << endl; //0x7ffee02f2710 (notice: even though c is instantiated inside f(), c resides in the stack frame of main()
cout << &afterC << endl; //0x7ffee02f26a8
return c;
}
C g() {
C c = f(); ///neither copy constructor nor move constructor of C are called, since none is done
cout << &c << endl; //0x7ffee02f2710
return c;
}
int main() {
int beforeC;
C c = g(); ///neither copy constructor nor move constructor of C are called, since none is done
int afterC;
cout << &beforeC << endl; //0x7ffee02f2718
cout << &c << endl; //0x7ffee02f2710 (notice:even though c is returned from f,it resides in the stack frame of main)
cout << &afterC << endl; //0x7ffee02f270c
return 0;
}
I'm sure a C++ expert will come along with a better answer, but personally I like the second approach. Using smart pointers helps with the problem of forgetting to delete and as you say, it looks cleaner than having to create an object before hand (and still having to delete it if you want to allocate it on the heap).

How can I be sure a routine is taking advantage of (N)RVO?

I'd like to make sure my routines are leveraging (N)RVO whenever possible. Other than parsing through the resulting disassembly, is there something I can do or check to see if a routine is being compiled with (N)RVO? At this point I'm mostly interested in MSVC and GCC.
No, not really.
However you can follow guidelines when writing your code.
Unnamed Return Value Optimization
This is pretty much triggered every time you return a temporary, even in Debug mode.
return MyObject(....);
Named Return Value Optimization
This is pretty much triggered every time the function always return the same local variable:
MyObject func() {
MyObject result;
if (...) { return result; }
result.push(0);
return result;
}
You can mix those, but it becomes nigh impossible for the compiler to apply RVO in this case:
MyObject func() {
MyObject result;
if (...) { return MyObject(...); }
return result;
}
Here, it is probably that one return will benefit from RVO and the other will not. And I would bet on the first being optimized because you'd be stuck if you speculatively create result in the return slot and suddenly need to take the if branch. Note that simply reordering the statements just work:
MyObject func() {
if (...) { return MyObject(...); }
MyObject result;
return result;
}
So the rule of thumb for NRVO is that there should be no return statement between the declaration of result and the return result; statement that return anything else than result itself.
If you follow this, you stack the odds in your favor. And then it's just a matter of code review.
And you also make your code easier to read since you do not declare variables before knowing that you really need them!
You can add debug methods to the destructor:
struct A
{
~A() { cout << "destructor called"; }
};
A foo()
{
A a;
return a;
}
If the destructor is called, RVO was probably not applied.
Possible ways I can think of are:
Implementing a reference counting mechanism within your class which keeps track of the number of instances created through the class, something pretty much like a shared_ptr does, This way You can detect extra copies of your class being created and removed if copy elision is not happening.
You could simply put debug traces in copy constructor and destructor for your class, if copy elision is not happening you would see lot of successive copy constructor and destructor debug traces.

c++ returning const reference of local variable

is it possible/ok to return a const reference even if the value the function returns is a local variable of this function? i know that locals are not valid anymore once the function returns - but what if the function is inlined and the returned value is only used within the callers scope? then the locals of the function should be included in the callers stackframe, no?
Don't count on it. Even if this works on 1 compiler, it's not standard supported behavior and is likely to break on others.
No, it's not OK. Local variables are declared on the stack, and the stack keeps changing between method calls. Also, the objects that get out of scope get destroyed. Always return a copy of a local variable.
Consider this code:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass() { cout << "ctor" << endl; }
~MyClass() { cout << "dtor" << endl; }
MyClass(const MyClass& r) { cout << "copy" << endl; }
};
const MyClass& Test()
{
MyClass m;
return m;
}
int main()
{
cout << "before Test" << endl;
MyClass m = Test();
cout << "after Test" << endl;
}
This will print out:
before Test
ctor
dtor
copy
after Test
dtor
The object you're trying to copy has already called its destructor and may be in an invalid state.
inline is not a guarantee -- it's a suggestion. Even if you use tricks to force inline, you'll never be sure about the result, especially if you want to remain portable.
Hence, don't do it.
Doing that invokes undefined behaviour.
There's no way of forcing a compiler to inline the function. inline is just a suggestion - so is __forceinline
Even if you could guarantee that the function would be inlined, the destructor for the variable in question will still be executed, leaving you with a reference to a dead object.
And the big one - C++'s concept of the stack is delimited by scope - not by function.
#include <iostream>
int main()
{
{
int a = 5;
std::cout << std::hex << "0x" << &a << std::endl;
}
{
int b = 10;
std::cout << std::hex << "0x" << &b << std::endl;
}
}
My compiler puts 'a' and 'b' at different memory address. Except when I turn optimizations on. Yours may well decide that it's an optimization to reuse the memory your object previously occupied.
Is there a paticular problem you're trying to solve here? There are other ways of reducing the number of temporary objects created if that's your concern.
As others have noted, this is dangerous. It's also unnecessary, if your compiler supports the NRVO (Named Return Value Optimization), and your function uses and returns the local variable you would have liked to return by ref in a fairly simple way.
The NRVO allows the compiler to avoid copy construction under certain conditions - typically the main reason to avoid returning objects by value. VC++ 8 supports this (a delta on previous revisions) and it makes quite a bit of perf diff in frequently used code.
The value falls out of scope when the callee falls out of scope. So no, it is gone.
But if you want a fairly ugly solution (and a red flag warning you that your design might need refactoring), you can do something like this:
const MyObj& GetObj()
{
static const MyObj obj_;
return obj_;
}
...but this solution if fraught with peril, especially if the object is modifyable, or does something non-trivial in a multithreaded environment.
The inline keyword doesn't guarantee that the function is really inlined. Don't do it.