Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy constructor with default parameters never gets called

Why is the output of the following program just int3 and not int3&4?

#include <iostream>

class B
{
public:
    explicit B(int i) { std::cout<<"int"<<i; }
    B(const B& rhs, int i = 0) { std::cout<<"&"<<i; }
};

int main(int, char**)
{
    B b(B(3), 4);
}

Command: clang++ test.cpp -O0

Compiler: Apple clang version 3.0 (tags/Apple/clang-211.12) (based on LLVM 3.0svn)

like image 582
David Lin Avatar asked Feb 29 '12 22:02

David Lin


2 Answers

Looks like you might have found a compiler quirk :)

If you change your compiler version to anything that's not LLVM 3.0, the output is int3&4.

This prints int3&4 on LLVm 3.0, so it seems to be related to the fact that B(3) is a temporary object:

class B
{
public:
    explicit B(int i)
    { 
        std::cout<<"int"<<i; 
    }
    B(const B& rhs, int i = 0) 
    { 
        std::cout<<"&"<<i; 
    }
};

int main(int, char**)
{
    B a(3);
    B b(a, 4);
}
like image 89
Carl Avatar answered Sep 30 '22 04:09

Carl


This was a bug in clang, which has since been fixed. Copy-elision was incorrectly being applied to the constructor call, because clang wasn't checking how many arguments were provided before concluding that it was a copy construction.

The fix will be in the upcoming clang 3.1 release.

like image 42
Richard Smith Avatar answered Sep 30 '22 04:09

Richard Smith