简体   繁体   中英

Data Alignment for C struct

There is a problem (3.45) in CS:APP about the byte offsets of all fields in the following struct.

struct {
  int    *a;
  float  b;
  char   c;
  short  d;
  long   e;
  double f;
  int    g;
  char   *h;
} rec;

Here is the answer from the book, which gives c a three bytes padding, d a two bytes padding and g a four bytes padding.

field  size  offset
-----  ----  ------
a      8     0
b      4     8
c      1     12
d      2     16
e      8     24
f      8     32
g      4     40
h      8     48

And here is my solution, which only gives c a one byte padding and g a four bytes padding.

field  size  offset
-----  ----  ------
a      8     0
b      4     8
c      1     12
d      2     14
e      8     16
f      8     24
g      4     32
h      8     40

So, what's the problem with my solution? It seems to fit the alignment rule (edit* the "rule" here is just a simplified concept summaries by myself, It's not completed or general), all object's offset is a multiple of the size of object.

Would be very thankful for any explanation.

Given the sizes of objects shown and alignment rules that say each of these objects must be aligned to a multiple of its size, then, when the structure is laid out with only the padding required for alignment, the offsets should be as shown in Tetrau's solution. The book solution is incorrect.

The offsets shown in Tetrau's solution are in fact the offsets produced by Apple LLVM 10.0.1 with Clang 1001.0.46.4 compiling for x86-64; the output from the program below is:

0
8
12
14
16
24
32
40
48
struct foo {
  int    *a;
  float  b;
  char   c;
  short  d;
  long   e;
  double f;
  int    g;
  char   *h;
} rec;


#include <stddef.h>
#include <stdio.h>


int main(void)
{
    printf("%zu\n", offsetof(struct foo, a));
    printf("%zu\n", offsetof(struct foo, b));
    printf("%zu\n", offsetof(struct foo, c));
    printf("%zu\n", offsetof(struct foo, d));
    printf("%zu\n", offsetof(struct foo, e));
    printf("%zu\n", offsetof(struct foo, f));
    printf("%zu\n", offsetof(struct foo, g));
    printf("%zu\n", offsetof(struct foo, h));
    printf("%zu\n", sizeof rec);
}

Note

The rule that an object requires alignment to a multiple of its size is fine for this exercise, but it should be noted it is not a general rule. A machine might have some eight-byte object but have only a bus and other memory access characteristics that are four bytes wide, so it would only care about four-byte alignment at most for any object. Or a structure member might be another structure that is, say, nine bytes in size (such as struct bar { char x[9]; } ), but its alignment requirement would not be nine bytes.

The answer depends on the compiler, platform and compile options. Some examples: 在此输入图像描述

https://godbolt.org/z/4tAzB_

The author of the book does not understand the topic I afraid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM