-1

A similar question asked on C++ here: What is the proper way of casting objects to unrelated objects in C++

#include <stdio.h>

typedef struct s1{

} s1;

typedef struct s2{

} s2;

int main(){
 s1 a;
 s2 b;
 
 b = *(s2*)&a;
 
 return 0;
}

Is using a bit cast the only way of accomplishing this?

Dan
  • 2,694
  • 1
  • 6
  • 19
  • 1
    I believe you can use a `union` between the two `struct`s. – LSerni May 09 '21 at 00:38
  • `of accomplishing this?` What is the code accomplishing? If it's accomplishing cast by itself, then it's doing it, but except for that the code is just invalid because empty structs are invalid. Ie. `What is the proper way` - what is a "proper" way? – KamilCuk May 09 '21 at 00:41
  • it's casting `a` to `b` not itself. – Dan May 09 '21 at 00:43
  • 4
    Whatever are you trying to do here? This code doesn't make any sense. If you want to copy it, use `memcpy()` and ensure the size of the two are identical. – tadman May 09 '21 at 00:45
  • That looks like a violation of [strict aliasing](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule?rq=1). – mediocrevegetable1 May 09 '21 at 12:02

1 Answers1

1

The C standard does not provide casting for structures and does not define the reinterpretation via pointer conversion shown in the question. (Certain such reinterpretations are supported for combinations of types specified in C 2018 6.5 7, but not for standalone structures.) The standard provides two other ways to reinterpret objects as another type.

First, one may simply copy the bytes of one object into another:

_Static_assert(sizeof a == sizeof b, "a and b must be the same size.");
memcpy(&b, &a, sizeof b);

For small objects, a good compiler with optimization enabled is likely to elide the copy and interpret the data in the new type directly from the memory or register(s) where it already is.

Second, one may store to one union member and read through another (C 2018 6.5.2.3 3, and see footnote 99):

_Static_assert(sizeof a == sizeof b, "a and b must be the same size.");
b = (union { struct s1 s1; struct s2 s2; }) {a} .s2;

The union type in parentheses starts a compound literal. The {a} gives a as an initial value for the union, specifically for the s1 member. Then .s2 accesses the s2 member.

Note that although the _Static_assert is included for some safety, you must also ensure the structure layouts are compatible for your purposes.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312