2016-03-24 2 views
1

Я анализирую возвращаемое значение по функции. Смотрите ниже фактического вопроса:Возвращаемое значение двумя копиями

struct S{ int a, b, c, d; }; 
S f(){ 
S s; 
s.b=5; 
return s; 
} 

int main(){ 
    S s= f(); 
    s.a =2; 
} 

вывод компилятора из gcc 5.3 -O0 -fno-elide-constructors on godbolt:

f(): 
     pushq %rbp 
     movq %rsp, %rbp 
     subq $32, %rsp 
     movl $5, -28(%rbp) 
     leaq -32(%rbp), %rdx 
     leaq -16(%rbp), %rax 
     movq %rdx, %rsi 
     movq %rax, %rdi 
     call S::S(S const&) 
     movq -16(%rbp), %rax 
     movq -8(%rbp), %rdx 
     leave 
     ret 
main: 
     pushq %rbp 
     movq %rsp, %rbp 
     subq $32, %rsp 
     call f() 
     movq %rax, -16(%rbp) 
     movq %rdx, -8(%rbp) 
     leaq -16(%rbp), %rdx 
     leaq -32(%rbp), %rax 
     movq %rdx, %rsi 
     movq %rax, %rdi 
     call S::S(S const&) 
     movl $2, -32(%rbp) 
     movl $0, %eax 
     leave 
     ret 

Что моя проблема?

  1. Почему здесь называются два экземпляра копии? Я не понимаю, зачем это нужно.
+8

Nononono, код лучше, чем ссылка. Кстати, эта ссылка выглядит _crazy_ и отформатирована как код, поэтому никто, вероятно, не посетит ее – ForceBru

+0

Если вы не хотите публиковать полный код здесь, это нормально. Но, по крайней мере, опубликуйте минимальную версию, в которой есть проблема, которую вы описываете. – BrainStone

+0

действительно не интересуется щелчком отрывочных ссылок в первую очередь. – djechlin

ответ

2

Кодирующий конструктор внутри f() вызывается, потому что используется «возврат» с объектом. Это побуждает его создать копию ее во временную переменную, а затем она будет передана в main. Скопируйте конструктор внутри main очевидно f() возвращает объект S, и его копируют в "s"

2

Один из двух раз, когда конструктор вызывается для создания временного объекта, используемого как возвращаемое значение f(). Если вы хотите избежать дополнительных накладных расходов, вам необходимо положиться на C++11 move constructors.

+0

Когда построен временный объект (пожалуйста, дайте мне количество строк) – Gilgamesz

+0

@Gilgamesz: В этом случае вы должны просто скомпилировать любой уровень оптимизации (даже минимальный '-Og' оптимизировать для отладки, а' f() 'будет компилироваться в' movabsq $ 21474836480,% rax'/'movl $ 0 ,% edx'/'ret'.' main() ', конечно, полностью оптимизируется.) –

Смежные вопросы