I don't think a conforming implementation is obliged to generate and compile a function body for the copy ctor here -- at least not based on the code given. What's missing is either odr-use or explicit defaulting after first declaration (see below).
It's the difference between
implicitly-declared vs.
implicitly-defined -- only the latter case would imply actual function body code generation possibility (although not the obligation, since the implementation is allowed to elide).
I think the implicitly-declared part is fine. In fact, in the C++03 Standard we had a clear wording "A copy constructor for class X is trivial if it is implicitly declared [...]", which is not present in the more recent draft I'm looking at (N4140).
Now, regarding the implicitly-defined part:
In N4140 this is 12.8 [class.copy] /13; we have: "A copy/move constructor that is defaulted and not defined as deleted is implicitly defined if it is odr-used (3.2) or when it is explicitly defaulted after its first declaration. [Note: The copy/move constructor is implicitly defined even if the implementation elided its odr-use (3.2, 12.2). —end note ]"
To illustrate the above -- here's a piece of code (with the generated assembly for illustration):
Code:
class A
{
int x;
double d;
};
int main()
{
A a;
}
/*
Clang 3.7:
main: # @main
push rbp
mov rbp, rsp
xor eax, eax
pop rbp
ret
GCC 4.9.2:
main:
push rbp
mov rbp, rsp
mov eax, 0
pop rbp
ret
Note: I have NOT odr-used any copy constructors (I've only odr-used `A`s default ctor) -- hence, no copy constructors are defined (implicitly or not).
Now, to see the contrast, let's odr-use `A`s trivial copy constructor:
Code:
class A
{
int x;
double d;
};
int main()
{
A a;
A b(a);
}
/*
Clang 3.7:
main: # @main
push rbp
mov rbp, rsp
xor eax, eax
mov rcx, qword ptr [rbp - 16]
mov qword ptr [rbp - 32], rcx
mov rcx, qword ptr [rbp - 8]
mov qword ptr [rbp - 24], rcx
pop rbp
ret
GCC 4.9.2:
main:
push rbp
mov rbp, rsp
mov rax, QWORD PTR [rbp-32]
mov rdx, QWORD PTR [rbp-24]
mov QWORD PTR [rbp-16], rax
mov QWORD PTR [rbp-8], rdx
mov eax, 0
pop rbp
ret
*/
Note that this is exactly as the Standard's note says -- "The copy/move constructor is implicitly defined even if the implementation elided its odr-use (3.2, 12.2). " -- so, the implementations (both with disabled optimizations, i.e., -O0; also both with -std=c++11) have elided the `call A::A(A const&)`, but it _is_ defined (with the corresponding data transfers via `mov` inlined into the generated `main`s body).
// (Note: members `x` and `d` are default-initialized to indeterminate values. I'm wondering, perhaps this was the reason for the interviewer's issue with copying things around?)