0

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;
}
Kavish Dwivedi
  • 735
  • 6
  • 24
  • 1
    http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization – Luchian Grigore Jul 09 '13 at 15:56
  • 6
    Why would you even expect it to call the copy constructor at all? `"copy me"` is a `const char [8]`, and not a `B`... –  Jul 09 '13 at 15:56
  • 7
    @H2CO3 because it's copy initialization. It should theoretically call it. – Luchian Grigore Jul 09 '13 at 15:56
  • 4
    @LuchianGrigore: Not even close. – Robert Harvey Jul 09 '13 at 15:56
  • @NoSenseEtAl no, it's not. copy & direct initialization are different. – Luchian Grigore Jul 09 '13 at 15:57
  • @LuchianGrigore Why is it copy initialization? –  Jul 09 '13 at 15:57
  • @NoSenseEtAl: Incorrect. That's only true if `a` and `b` have the same type. Otherwise, these two forms of initialization are not the same. In the OP's case the types are not the same. – AnT stands with Russia Jul 09 '13 at 15:57
  • @RobertHarvey what do you mean? – Luchian Grigore Jul 09 '13 at 15:58
  • 1
    @Luchian: In order for that question to be a duplicate, it would have to be more or less in the form "Why is the wrong copy constructor being called?" – Robert Harvey Jul 09 '13 at 16:00
  • I would recommend to use one default constructor and one constructor with one arguemnt and declare that `explicit`. – typ1232 Jul 09 '13 at 16:02
  • @LuchianGrigore i know i confused it with (f) http://herbsutter.com/2013/05/09/gotw-1-solution/ – NoSenseEtAl Jul 09 '13 at 16:02
  • @LuchianGrigore I'm in your corner on this. The compiler may not actually generate the "call", but as you have pointed out to me in a prior question by me some time ago (seems forever ago) the standard supports creating a temp `B` from "copy me", then firing the class copy-ctor. I remember this only because in my case the compiler yelled at me for not providing a copy-ctor that it then proceeded to not call anyway, but had to be provided to be standard compliant. I'd have to search to find my old question, but I think you pointed me to the same link at the top of these comments. – WhozCraig Jul 09 '13 at 16:03
  • @RobertHarvey but I didn't mark it as a dupe, I was merely providing a source. :) I didn't vote to close. – Luchian Grigore Jul 09 '13 at 16:04
  • I thought a temporary was created here and then copied but it seems that copy epsilon is probably an optimization technique by the compiler . – Kavish Dwivedi Jul 09 '13 at 16:05
  • 3
    @KavishDwivedi Using g++, if you compile with the `-fno-elide-constructors` switch, you'll see a call to the copy constructor. Otherwise, pretty much every compiler will elide that copy. – Praetorian Jul 09 '13 at 16:06
  • @RobertHarvey Is http://stackoverflow.com/questions/4292021/no-call-to-the-copy-constructor better? Now it is your turn, my close vote is gone. – Tadeusz Kopec for Ukraine Jul 09 '13 at 16:22

1 Answers1

8

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).

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • +1 the second paragraph is also notable for VC++ (at least through 2010). It behaves the same way, as i discovered, and eluded to in my comment in the general section above. – WhozCraig Jul 09 '13 at 16:09
  • yeah , 2nd paragraph about declaring it private pretty much explains everything – Kavish Dwivedi Jul 09 '13 at 16:09
  • 1
    Note: you can disable copy elision in g++ with the `-fno-elide-constructors` option. (Edit: I hadn't seen [Praetorian's comment](http://stackoverflow.com/questions/17552785/why-is-copy-constructor-not-called-in-this-case#comment25532859_17552785)...) – gx_ Jul 09 '13 at 16:12
  • 1
    eluded != alluded @WhozCraig – bames53 Jul 09 '13 at 16:15
  • @bames53 lol. hate when that happens. I'm always doing it too. thanks!. – WhozCraig Jul 09 '13 at 22:42