Placing new - saving buffer value

Is there a way to keep the original value of the buffer passed to the new placement? Code example:

struct MyStruct {
  int number;
  char bytes[100];
} __attribute__ ((packed));

char data[sizeof(MyStruct)]; // contains value received via TCP

MyStruct* create_struct_a() {
  char tmp[sizeof(MyStruct)];
  memcpy(tmp, data, sizeof(MyStruct));
  MyStruct* result = new (data) MyStruct;
  memcpy(result, tmp, sizeof(MyStruct));
  return result;
}

MyStruct* create_struct_b() {
  return new (data) MyStruct;
}

gcc 5.3 produces the same asm code for both functions when MyStruct :: bytes is small:

create_struct_a():
    movl    $data, %eax
    ret
create_struct_b():
    movl    $data, %eax
    ret

but when the size of MyStruct :: bytes exceeds 150 gcc 5.3, you will get:

create_struct_a():
    subq    $168, %rsp
    movl    $154, %edx
    movl    $data, %esi
    movq    %rsp, %rdi
    call    memcpy
    movq    %rsp, %rsi
    movl    $154, %edx
    movl    $data, %edi
    call    memcpy
    movl    $data, %eax
    addq    $168, %rsp
    ret
create_struct_b():
    movl    $data, %eax
    ret

I need a smaller asm code without memcpy for a larger structure, but can't find a legal way to get the compiler to do this. char data[sizeof(MyStruct)]will also be used to store other packed types with size <= sizeof(MyStruct), so the data type should char[sizeof(MyStruct)]not MyStruct.

+4
source share

All Articles