I was just reading the pset4 text and can't get my head around this part:

As this figure suggests, order does matter when it comes to structs' members. Byte 57 is rgbtBlue (and not, say, rgbtRed), because rgbtBlue is defined first in RGBTRIPLE. Our use, incidentally, of the attribute called packed ensures that clang does not try to "word-align" members (whereby the address of each member’s first byte is a multiple of 4), lest we end up with "gaps" in our structs that don’t actually exist on disk.

How can clang "word-align", what would that mean, why does the address of each member's first byte become a multiple of 4 then and how do we end up with gaps in our stucture when it's just a variable type that consists of other variables which would mean that its an array?


Arrays vs Structures

First off, a struct is not the same thing as an array. structs and arrays are different data types. They have similarities (e.g., they are both complex data types, they can group one or more values, etc.)

However, there are major differences too, including that they are used in different contexts, array members are of the same data type, while struct members do not have to be of the same data type, array elements are accessed by means of a zero-based index (e.g., using the bracket notation), while struct members may be accessed using their names (with the dot operator), and so on.

Watch the shorts on "Structures" and "Arrays" for more info!


The SO answer linked in the comment above explains that quite well. Nevertheless, let's try to simplify this a bit!

A variable is simply a location in memory. A memory location has a numerical address. When data gets read from or written to memory, this is done in word-sized chunks.

What's the size of a word? Well, that's different from one computer to another. On the CS50 IDE, the size of a word is 8 bytes (64 bits), so data gets read/written in 8-byte chunks. For that reason, when reading data, for example, it's better if that data is stored at a memory block that starts at a location whose address is a multiple of 8 (I think the multiple of 4 bit is dated?)

Getting data to be stored at a memory block that starts at a location whose address is multiple of the word size is called word-aligning. Typically, this is done by inserting some meaningless bytes, referred to as padding.

But what happens if the data is not word-aligned? In that case, the computer may have to do some extra work in order to retrieve that data. For example, suppose we want to read one byte of data from location 17. To get that, the computer would have to read the word that starts at location 16, then left-shift to get my data.

This other SO answer gives another great explanation (with visualization this time!) It assumes the size of a word is 4 bytes though, so mind that!

What does this have to do with BMPs?

Speed is not our concern here really. We're more concerned about how the data is organized in memory. A BMP viewer, for example, expects the data of the BMP to be viewed to stored exactly in that order:

enter image description here

To prevent the members of any of these structs from getting word-aligned (thus, some locations would change), we need to use the __attribute__((__packed__)) type attribute, per bmp.h.

| improve this answer | |

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .