Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Standard compliant way of swapping bits of two objects in different types

Consider the following two functions:

template<typename T, typename S>
template<typename T, typename S>
void swap1(T* t, S* s)
{
  static_assert(sizeof(T) == sizeof(S));
  char tmp[sizeof(T)];
  std::memcpy(tmp, t, sizeof(T));
  std::memcpy(t,  s, sizeof(T));
  std::memcpy(s, tmp, sizeof(T));
}

and

template<typename T, typename S>
void swap2(T* t, S* s)
{
  static_assert(sizeof(T) == sizeof(S));
  char *tc = (char*)t, *sc = (char*)s;
  std::swap_ranges(tc, tc + sizeof(T), sc);
}

Which of them violates the strict aliasing rule? Do both of them violate the rule? If both, how to achieve the goal without violation?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

All I can see from C++ standard is that, we can use pointers of certain types including char* to point at an arbitrary object, and access its stored value. What does access mean? Is it just read or read+write?

I didn’t find an emphatic answer from this post.

Discussion on this post confused me even more.

But by reading the "memcpy version, compliant to C and C++ specs and efficient" section of this post, it seems at least swap2 is perfectly fine.

>Solution :

Neither implementation violates the strict aliasing rule. The rule prohibits reading or writing T* via U* unless U* is char*/unsigned char*/std::byte*. Reading and writing through char* is perfectly standard C++.

Whether the object ends up having some value in the end is a whole another story. I don’t think standard guarantees anything unless T and U are the same type. Maybe barring some arithmetic conversions. But I’m not sure.

If you only have a single trivially copyable type T, [basic.types]/2 says (omitting some details):

For any object … of trivially copyable type T … the underlying bytes … making up the object can be copied into an array of char
If the content of that array is copied back into the object, the object shall subsequently hold its original value.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading