0

Trying to respond to another question, I've proposed a solution that use std::memcpy() to store generic types in a buffer of chars.

My doubt is about possible memory alignment issues storing POD (I know that with not-POD type, as std::string, is very very dangerous).

In short: there are memory alignment issues with the following program?

And if they are, it's possible to write something similar (that store POD values in a char buffer) that is safe? And how?

#include <cstring>
#include <iostream>

int main()
 {
   char  buffer[100];

   double  d1 { 1.2 };

   std::memmove( buffer + 1, & d1, sizeof(double) );

   double  d2;

   std::memmove( & d2, buffer + 1, sizeof(double) );

   std::cout << d2 << std::endl;

   return 0;
 }
Community
  • 1
  • 1
max66
  • 65,235
  • 10
  • 71
  • 111
  • This should work. In general should check sizeof() less than fixed buffer, but of course a double is way less than the 100 used here. – Gregg Oct 03 '16 at 13:29
  • @Gregg - Of course; I've used `100` to avoid doubts about the size of the buffer. – max66 Oct 03 '16 at 13:33

2 Answers2

5

This is safe.

[basic.types]/2: For any trivially copyable type T, if two pointers to T point to distinct T objects obj1 and obj2, where neither obj1 nor obj2 is a base-class subobject, if the underlying bytes (1.7) making up obj1 are copied into obj2, obj2 shall subsequently hold the same value as obj1.

Since double is trivially copyable, your code is well-defined.

TartanLlama
  • 63,752
  • 13
  • 157
  • 193
3

You can copy to and from an unaligned buffer. What you can't do is cast the buffer to a double * and then operate directly on the value in memory, as a double. Often that will cause an error because of alignment issues.

Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18
  • 2
    "*Technically assigning random bytes to a char is undefined because of trap representations.*" Not according to the standard. [basic.types]/2 says you can use `char` or `unsigned char` for trivial copying of objects. – Nicol Bolas Oct 03 '16 at 13:43
  • So that's a glitch in the standard. char is allowed a trap representation and one of the clauses must be incorrect. In fact the author nodded and the type must be unsigned char. – Malcolm McLean Oct 03 '16 at 14:20
  • 1
    There's no glitch. `char` is permitted to be signed or unsigned. `signed char` may or may not have a trap representation. In order for an implementation to be in line with the standard, if `signed char` can trap, then `char` *must not be signed*. So a 2's complement signed `char` type is perfectly valid. There are other places in the standard with such a requirement, such as the UTF-8 requirements on `char` (being able to convert any UTF-8 code between `char` and `unsigned char` requires `char` not trap). – Nicol Bolas Oct 03 '16 at 14:29
  • Edited to remove statement about char trapping. – Malcolm McLean Oct 03 '16 at 14:42