Reputation: 2886
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.
Upvotes: 2
Views: 160
Reputation: 311088
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
Upvotes: 4