No call to the copy constructor - c++

Consider this:
#include <iostream>
struct A{
A(){
std::cout << "Create empty A" << std::endl;
}
A(const A& a){
// Why is this never called??
std::cout << "Never called" << std::endl;
}
};
A genA() {
A a;
return a;
}
int main(int argc, const char *argv[])
{
A a(genA()); // Expected to call copy constructor
return 0;
}
Why is the copy constructor not called?
What should I do if I want to ensure that "Never called" is printed on the screen every time I copy A.

This is called as Return value optimization.
Compiler can optimize your code so that it bulds the object directly in the location where it would have been copied too. Thus there will be no reason to use the copy constructor.
Note: The standard explicitly allows it do so.

One way you can force the compiler to avoid RVO is to not return by value - e.g.
#include <iostream>
#include <memory>
struct A{
A() {
std::cout << "Create empty A" << std::endl;
}
A(const A& a) {
// This will be called now
std::cout << "Never called" << std::endl;
}
};
std::auto_ptr<A> genA() {
return std::auto_ptr<A>(new A);
}
int main(int argc, const char *argv[])
{
A a(*(genA().get())); // this will trigger the copy-ctor
return 0;
}
Though this is a horrible hack. I would instead ask why you want to do this? and if you are hoping to put some side-effects into the constructor, urge you to think otherwise.

Copy constructor invocations can be elided (even if they contain side effects), the standard allows that ([12.2]).
EDIT:
I suggest that you do not try to fight it in real world code.
If you just want to see the copy ctor executed in some example/turorial code, then it usually helps not to compile with optimization. Some compilers even have switches that help to avoid that. For GCC it should be -fno-elide-constructors.

Related

Why can copy elision not optimise all copy operations?

I read about copy elision and how it can fasten up Programms by giving possibilities to write code more straight foreword without thinking about references of variables.
In a small example I tried to find the limits of this technique.
#include <iostream>
class A
{
public:
A(){}
A(const A &a) {std::cout << "Copy" << std::endl;}
};
A foo(A a)
{
return a;
}
int main(void)
{
A a = foo(foo(A()));
std::cout << std::endl;
A b;
b = foo(foo(b));
return 0;
}
https://godbolt.org/z/xo88jq
Output:
Copy
Copy
Copy
Copy
Copy
The compiler already elides many of the copies in this example.
But why is the compiler not able to elide all those copies leading to a or in the modification of b?

Move constructor is not called when using boost::pool_allocator

I have the following simple test code.
#include <stack>
#include <iostream>
#include "boost/pool/pool_alloc.hpp"
struct Frame
{
uint32_t i{};
Frame(uint32_t _i) : i(_i) {}
Frame(const Frame& f)
{
std::cout << "Copy constructor" << std::endl;
i = f.i;
}
Frame(Frame&& f)
{
std::cout << "Move constructor" << std::endl;
std::swap(i, f.i);
}
};
int main(int argc, char* argv[])
{
{
std::stack<Frame, std::deque<Frame>> stack;
Frame f(0);
stack.push(std::move(f)); // Move constructor
stack.push(Frame(1)); // Move constructor
}
{
std::stack<Frame, std::deque<Frame, boost::pool_allocator<Frame>>> stack;
Frame f(0);
stack.push(std::move(f)); // Copy constructor
stack.push(Frame(1)); // Copy constructor
}
return 0;
}
When I compile this code with either Clang or GCC, it gives me the following output:
Move constructor
Move constructor
Copy constructor
Copy constructor
Why does using boost::pool_allocator prevent the compiler from using the move constructor?
Am I missing something?
pool_allocator does not perfect forward the arguments to construct: It simply takes a const reference to the value type and passes that on as the initializer for placement new.
That is because pool_allocator has not been updated for C++11 yet.

C++ const std::string assignment

What is most appropriate in const std::string assignment/declaration? Using the constructor(e.g., const std::string WORD("hello");) or using equal operator(e.g., const std::string WORD= "hello";)?
Does these things has difference in memory usage or time processes?
For any reasonable compiler, the code generated will be the same in both cases. Whether you should use direct initialization or copy-initialization in this case is essentially opinion-based.
In both cases, generally compilers will remove the copies using "Return Value Optimisation" anyway. See this code on ideone here calls neither the ordinary constructor nor the assignment operator as it doesn't print that they're being called to screen:
That is:
#include <iostream>
class C
{
public:
C() {}
C(const char[]) { std::cout << "Ordinary Constructor" << std::endl; }
C& operator=(const char[]) { std::cout << "Assignment Operator" << std::endl; return *this; }
};
int main() {
std::cout << "Start" << std::endl;
C x1 = "Hello";
C x2("Hello");
std::cout << "End" << std::endl;
}
Simply outputs:
Start
End
It doesn't output:
Start
Assignment Operator
Ordinary Constructor
End
As C++ allows the copies to be skipped and the temporary to be constructed in place.
The lines:
std::string x = "hello";
std::string x("hello");
both will only call the constructor of std::string. That is, they are identical, and neither will use the operator= overloads.

constructor and copy constructor behaviour in c++ [duplicate]

This question already has answers here:
Why copy constructor is not called here?
(2 answers)
Closed 8 years ago.
I have the following code:
#include <iostream>
using namespace std;
class X
{
public:
int g;
X() { cout << "constr" << endl; }
X(const X& ref1) { cout << "copy constr" << endl; }
};
X f()
{
X ee;
ee.g = 1;
return ee;
}
int main()
{
X ff = f();
return 0;
}
Running the code I see that the constructor was called only once and the copy constructor was never called. Don't you expect two constructor and one copy constructor calls here? Thanks!
This is a special case of the copy elision called return value optimization (the link explains precisely your case).
Copy Elision is an optimization implemented by many compilers to prevent extra, unnecessary, copies. Makes the return-by-value or pass-by-value possible in practice.
Take a look at the example in the following answer: https://stackoverflow.com/a/12953129/1938163
struct C {
C() {}
C(const C&) { std::cout << "A copy was made.\n"; }
};
C f() {
return C();
}
int main() {
std::cout << "Hello World!\n";
C obj = f();
}
(http://en.wikipedia.org/wiki/Return_value_optimization#Summary)
Perhaps incredible to believe the first time, depending on the compiler & settings, the following outputs are all valid:
Hello World!
A copy was made.
A copy was made.
Hello World!
A copy was made.
Hello World!
In your case, this is a special copy elision optimization called RVO - Return Value Optimization where an object returned by value from a method has its copy elided.

Why is copy-constructor not called in this case?

I encountered a code snippet and thought that it would call copy-constructor but in contrast , it simply called normal constructor . Below is the code
#include <iostream>
using namespace std;
class B
{
public:
B(const char* str = "\0")
{
cout << "Constructor called" << endl;
}
B(const B &b)
{
cout << "Copy constructor called" << endl;
}
};
int main()
{
B ob = "copy me";
return 0;
}
What you've discovered that B ob = "copy me"; notionally creates a B from the literal and then copy constructs ob, but that the compiler is allowed to elide the copy and construct directory into ob. g++ even elides the copy with no optimization enabled at all.
You can observe that this is the case by making your copy constructor private: The code will fail to compile even though the compiler won't actually use the copy constructor (the standard requires that copy constructors be accessible even when the call is elided).