Design Article
Padding and rearranging structure members
Dan Saks
5/11/2009 12:00 AM EDT
A couple of months ago, I showed how a C++ delete-expression is actually a two-step process: (1) apply a destructor to the object in the allocated storage, and (2) deallocate the storage.1 In an array-delete-expression, the first step is actually a loop, which applies the destructor to each array element.
When I described the implementation of the loop, I omitted the details of how a delete-expression determines the array dimension. I promised to present those details--and I will--but not just yet. The details draw upon an understanding of memory alignment and the use of padding in structures, which are my topics this month.
Alignment
Many of today's processors can address memory one 8-bit byte at a time. They can also access memory as larger objects such as 2- or 4-byte integers, 4-byte pointers, or 8-byte floating-point numbers.
Multibyte objects often have an alignment. The C Standard defines alignment as a "requirement that objects of a particular type be located on storage boundaries with addresses that are particular multiples of a byte address".2 The Standard leaves it up to each target processor to specify its alignment requirements. That is, a processor might require that a 4-byte integer or pointer referenced as a single object be word aligned--at an address that's a multiple of four. A processor also might require that an 8-byte floating-point number be word aligned, or maybe even double-word aligned--at an address that's a multiple of eight.
According to the C Standard, a program that attempts to access an improperly aligned object produces undefined behavior. This means that the program is in error, but the exact consequences of that error are platform-dependent. With many processors, an instruction that attempts to access improperly aligned data issues a trap. With other processors, an instruction that accesses misaligned data executes properly but uses up more cycles to fetch the data than if the data were properly aligned.
An object whose address requirement is a higher multiple than another is said to have a stricter alignment. For example, an object that must be double-word aligned (at an address that's a multiple of eight) has a stricter alignment than an object that must be only word aligned (at an address that's a multiple of four). Character objects always have a size of one (by definition) and can reside at any boundary. They have no alignment requirement.
Machines with 4-byte words and 8-byte double words are very common but hardly universal. The following discussion uses these common sizes for illustrative purposes only. Please bear in mind that machines with other word sizes and alignment requirements do exist.




krwada
5/28/2009 7:33 PM EDT
This is a great article about a pretty obscure, but nevertheless vital subject for embedded systems design. A few points here:
Alignment is critical in DSP, (Digital Signal Processor) based systems. Most DSP's achieve 32-bit alignment by storing part of the word with the LSB=0, and storing the other pat with the LSB=1. The chip vendors do this to save on hardware I believe.
In general, it is better to use "copy by value" instead of the older memcpy(). Here is an example, (works both in C and C++)
typedef struct exampleStruct
{
unsigned char cv;
unsigned int iv;
void *ptr;
} exampleStruct;
extern exampleStruct *p_src;
exampleStruct my_dst;
memcpy
memcpy (&my_dst, p_src, sizeof(exampleStruct));
Copy by value
my_dst = *p_src;
Even though both examples are equally valid, and produce the correct result; I believe the copy-by-value to be less prone for error, and 'inadvertent mistakes' by the programmer.
Sign in to Reply
Patrick Perdu
9/13/2010 2:55 PM EDT
As a matter of good practice, for critical embedded code, I insist that the padding be explicit in the structures.
I have seen some engineers complain that it is inefficient and introduces risks of more inefficiencies during maintenance if the structure has to be changed, but in my experience it is safer to make sure that the engineer did pay attention to the issue.
As for maintenance, if explicit padding bytes are part of the coding standards for critical-level projects, then there is very little risk as errors will be caught at code review.
Sign in to Reply