Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

struct alignment C/C++

In c/c++ (I am assuming they are the same in this regard), if I have the following:

struct S {   T a;   .   .   . } s; 

Is the following guaranteed to be true?

(void*)&s == (void*)&s.a; 

Or in other words, is there any kind of guarantee that there will be no padding before the first member?

like image 858
Baruch Avatar asked Jul 24 '13 21:07

Baruch


People also ask

Are structs 8 byte aligned?

struct foo1 { char *p; char c; long x; }; Assuming a 64-bit machine, any instance of struct foo1 will have 8-byte alignment.

What is struct padding in C?

The structure padding is automatically done by the compiler to make sure all its members are byte aligned. The size of the below structure is 16 bytes due to structure padding: Struct dummy { Char ch; Int num; Double temp; } Here 'char' is only 1 byte but after 3 byte padding, the number starts at 4 byte boundary.

What is structure member alignment?

Data structure alignment is the way data is arranged and accessed in computer memory. Data alignment and Data structure padding are two different issues but are related to each other and together known as Data Structure alignment.


2 Answers

In C, yes, they're the same address. Simple, and straightforward.


In C++, no, they're not the same address. Base classes can (and I would suspect, do) come before all members, and virtual member functions usually add hidden data to the struct somewhere. Even more confusing, a C++ compiler may also rearrange members at will, unless the class is a standard layout type (though I don't know that any compiler does so)

Finally, if the C++ struct is composed of standard layout types, contains no base classes nor virtual functions and all members have the same visibility, and possibly other limitations I forgot, then it falls back on the C rules, and requires the first member to be at the same address as the object itself.

§ 9.2/7

A standard-layout class is a class that:
— has no non-static data members of type non-standard-layout class (or array of such types) or reference,
— has no virtual functions (10.3) and no virtual base classes (10.1),
— has the same access control (Clause 11) for all non-static data members,
— has no non-standard-layout base classes,
— either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
— has no base classes of the same type as the first non-static data member.

§ 9.2/20

A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [ Note: There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. —end note ]

like image 111
Mooing Duck Avatar answered Sep 30 '22 20:09

Mooing Duck


Yes, it is.

It is guaranteed there is no padding before the first struct member in C and in C++ (if it is a POD).

C quote:

(C11, 6.7.2.1p15) "There may be unnamed padding within a structure object, but not at its beginning."

C++ quote:

(C++11, 9.2p20) "There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment"

like image 28
ouah Avatar answered Sep 30 '22 20:09

ouah