https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82910
Bug ID: 82910 Summary: marking data members private affects code generation of copying Product: gcc Version: 7.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: vanyacpp at gmail dot com Target Milestone: --- Consider the following piece of code: struct pair { private: void* first; unsigned second; }; struct other { pair get() const; }; struct my { pair get(other const& other); pair current; pair* target; }; pair my::get(other const& other) { *target = other.get(); return current; } For the function my::get() GCC generates the following (quite inefficient) code: my::get(other const&): pushq %rbx movq %rdi, %rbx movq %rsi, %rdi subq $16, %rsp call other::get() const movq 16(%rbx), %rcx movq %rax, (%rsp) movq %rdx, 8(%rsp) movq %rax, (%rcx) movl 8(%rsp), %eax movl %eax, 8(%rcx) movq (%rbx), %rax movq 8(%rbx), %rdx addq $16, %rsp popq %rbx ret The expected generated code is: my::get(other const&): pushq %rbp pushq %rbx movq %rdi, %rbx subq $8, %rsp movq 16(%rdi), %rbp movq %rsi, %rdi call other::get() const movq %rax, 0(%rbp) # just storing to *my::target... movq %rdx, 8(%rbp) movq (%rbx), %rax # ... and then loading my::current movq 8(%rbx), %rdx addq $8, %rsp popq %rbx popq %rbp ret The issue can be worked around. One way to do this is to make the data members of pair public. Another way is changing pair::second type to unsigned long (to match the size of pointer). It would be great is GCC generates the second code irrespectively of private-ness or the size of pair::second.