0

When I do int a = std::move(b) (b is int also), is it same as just a = b?

Wei Ding
  • 31
  • 1
  • 3

1 Answers1

5

Depends on the compiler! The assembler for the variant with std::move without optimization will try to remove the "reference" even though it is unnecessary, which the ASM code for the variant without std::move will not - this gives you a slight overhead (a call to std::move which contains a few instructions and an additional movl on the top level) in terms of CPU instructions!

Test Code:

Example without optimization using GCC 8.2 in X86_64 assembler:

#include <stdio.h>

int main()
{
    c = b;
    return 0;
}


int alternative()
{
    c = std::move(b);
    return 0;
}

Assembler O0:

main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    b(%rip), %eax
        movl    %eax, c(%rip)
        movl    $0, %eax
        popq    %rbp
        ret

alternative():
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $b, %edi
        call    std::remove_reference<int&>::type&& std::move<int&>(int&)
        movl    (%rax), %eax
        movl    %eax, c(%rip)
        movl    $0, %eax
        popq    %rbp
        ret

std::remove_reference<int&>::type&& std::move<int&>(int&):
        pushq   %rbp
        movq    %rsp, %rbp
        movq    %rdi, -8(%rbp)
        movq    -8(%rbp), %rax
        popq    %rbp
        ret

However, if you turn on optimization (-O3), it really becomes the same in terms of CPU instructions:

main:
        movl    b(%rip), %eax
        movl    %eax, c(%rip)
        xorl    %eax, %eax
        ret

alternative():
        movl    b(%rip), %eax
        movl    %eax, c(%rip)
        xorl    %eax, %eax
        ret
Skriptkiddie
  • 411
  • 2
  • 7
  • weird -- I would have expected a call to `std::move` in the unoptimized code rather than a call to anything else. It appears the compiler is still inlining some calls despite -O0. Why it inlines the call to std::move and not the call to std::remove_reference is a mystery, – Chris Dodd Dec 01 '18 at 03:41
  • Maybe it is the strange Intel syntax that causes confusion here :/ Added the ASM for `std::remove_reference::type&& std::move(int&):` which I agree is a very strange name. – Skriptkiddie Dec 01 '18 at 03:45
  • Ah, no makes sense -- that is the `std::move` function that is being called -- its just that it gets a mangled name including the argument (and return?) types, that you are then demangling. – Chris Dodd Dec 01 '18 at 03:51
  • Yeah, I was also confused by that strange "naming convention" :/ – Skriptkiddie Dec 01 '18 at 03:52
  • 1
    There is really very little point in looking at what the compiler does in unoptimized code. Unoptimized code is deliberately crippled in order to make debuggers follow the same path as the source code. – Galik Dec 01 '18 at 05:42