Maker Function Initialization: Standard or Compiler Specific

H

Haochen Xie

Hi everyone,

I just made a test on how C++ would behave when trying to use an object maker function to initialize a variable and my test code gave me the followingresults:

Results:
===============
Before makeBar_val is called
makeBar_val called
Bar 28feff is constructed
After makeBar_val is called, got 28feff
Bar 28feff is destructed
===============

the code is pasted with this post, and also available on pastebin.com: <http://pastebin.com/iKEFv5r5> (pastid: iKEFv5r5).

The code was compiled with mingw32(gcc version 4.6.1 (GCC)) without any optimization option.

The result is what I expected, so the constructor of Bar is only called foronce and the scope of the Bar made by the make function is passed to main(), like the variable bar in main() is directly initialized in place. So here comes my question: is this kind of "inlining" required by the C++ standard or just a smart compiler optimization? Can I assume all compiler would generate a program working like this example? Can I assume the result would be the same if I'm using a non-trivial maker function?

Code:
===============
#include <cstdio>

class Bar
{
public:
// Conster & Dester
Bar() { printf("Bar %x is constructed\n", this); }
~Bar() { printf("Bar %x is destructed\n", this); }

//Copier
Bar(const Bar& bar)
{
printf("Bar is copied (copy constructor is called): "
"%x -> %x\n", &bar, this);
}
const Bar& operator=(const Bar& rhs)
{
printf("Bar is assigned (operator= is called)\n");
return rhs;
}
};

Bar makeBar_val()
{
printf("makeBar_val called\n");
return Bar();
}

int main()
{
printf("Before makeBar_val is called\n");
Bar bar(makeBar_val());
printf("After makeBar_val is called, got %x\n", &bar);
}

===============
 
Ö

Öö Tiib

the code is pasted with this post, and also available on pastebin.com:
<http://pastebin.com/iKEFv5r5> (pastid: iKEFv5r5).

So here comes my question: is this kind of "inlining" required by the C++
standard or just a smart compiler optimization?

It is optimization that C++ standard claims to be valid. Return value
optimization ... RVO. The class must still have copy constructor even if
copy does not happen.
Can I assume all compiler would generate a program working like this example?

No. However it is almost hard to implement a compiler without that. The
functions that return a value of class type usually have additional
hidden parameter to store that return value in most implementations. It
is complex to implement such function without that parameter.
Can I assume the result would be the same if I'm using a non-trivial
maker function?

No. For example if the maker makes several objects and then chooses
to return one then compiler can not decide what is the returned object
and so copy to return value will happen. Also some older compilers still
fail doing it on simpler cases as well despite it is very easy.

Avoid having copy constructors and destructors with surprizing
side-effects. It will confuse yourself few months later.
 
H

Haochen Xie

Thank you for replying, Paavo & Öö. Actually I want to implement a resource managing object relying on the elimination of the destructor call. So if the RVO is just a optional optimization, and the mover is not guaranteedto be called, I may come up with some more complex design.

Thank you again.
 
H

Haochen Xie

In C++11 this more complex design might be implemented quite easily by
prohibiting the copy constructor (and assignment operator) and by providing
a move constructor which moves the resource ownership from one object to
another. There is also std::unique_ptr doing roughly the same. The only
problem might be that C++11 is not yet very widely supported by different
compilers.

Yeah, I just realized that is the most efficient way to achieve the behavior what I want and I'm definitely going to do that, since I'm developing my own library (a light wrapper of sqlite3, as both an exercise to Efficient C++ and a relief from manual resource managing when using the C API) and I always use gcc with -std=gnu++0x option. So the supporting for C++11 is not a problem :)

Thank you again for your reply!

Haochen Xie
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top