Is casting a struct to an integer legal?

160 Views Asked by At
struct test{
  int num;
};

int main(){
 struct test t = {1234};
 int n = *((int*)&t); // n = 1234
 
 return 0;
}

Is the above snippet legal and causes no undefined behavior? I have seen this similar code snippet in production.

Edit: Please forgive the C style cast being used here.

1

There are 1 best solutions below

20
On BEST ANSWER

The structure

struct test{
  int num;
};

is a standard layout structure. It is guaranteed that its data member num is at zero offset in the structure test.

Standard layout structures are useful for communicating with code written in other programming languages as for example in C.

In C the address of an object of a structure type is equal to the address of its first data member.

From the C Standard (6.7.2.1 Structure and union specifiers)

15 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

So this code snippet

int n = *((int*)&t);

is valid and well-formed.

Instead of the C casting it is better to use the C++ casting reinterpret_cast.

As @HolyBlackCat pointed to in his comment (For example the C++ 20 Standard, 6.8.3 Compound types)

4 Two objects a and b are pointer-interconvertible if:

//...

(4.3) — one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, any base class subobject of that object (11.4), or

//...

If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast