What am I missing in this K & R example?

The following is a snippet from the sample code in the K & R C programming language (section 8.7):

typedef long Align;

union header {
    struct {
        union header *ptr;
        unsigned size;
    } s;
    Align x;
};

typedef union header Header;

And here is an explanatory excerpt:

To simplify alignment, all blocks are multiples of the size of the title, and the title is aligned correctly. This is achieved by a union that contains the required header structure and an instance of the most restrictive type that we arbitrarily made long.

So, I understand, the idea is for the instance to headeroccupy several bytes, a multiple of the value sizeof(Align). The goal makes sense to me.

But consider the case where long- 64 bits, int- 32 bits, and a pointer - 64 bits. In this case there header.swill be 64 + 32 = 96 bits. Thus, there sizeof(header)will be 96 bits, which will not be a multiple of 64, as intended.

, , Align (, double). , , . " " ? , long - - , ?

+3
5

header, ptr, size x header[]. x , sizeof(header) sizeof(long).

+3

. , sizeof(s) 12, sizeof(long) 8, , sizeof(header) >= 12. , , long , header , , long, 8.

, , sizeof(header) 16, 12. , header, , , . , . , 4 header.

+3

, . . , .

, , . , , . , , .

, , . . 32- , . longs 64- , 128 .

+1

( ), K & R, , . typedef + sizeof .

, ( ), 32- , . , /, .

0

, sizeof (Align) sizeof (s). .

#include <limits.h>
#include <stdio.h>

typedef long Align;

typedef union header {
    struct {
        union header *ptr;  /* 64 bits */
        unsigned size;    /* 32 bits */
    } s;                    /* subtotal 96 */
    Align x;                /* 64 bits -> should be greater than 96 */
} Header;                  /* total 128 bits */

typedef struct hair {
    union header *ptr;  /* 64 bits */
    unsigned size;      /* 32 bits */
} Hair;              /* subtotal 96 */

int main(void)
{
    Header u;
    Hair h;

    printf("char %ld bits, %ld bytes\n", sizeof(char)*CHAR_BIT,(sizeof(char)*CHAR_BIT)/8);
    printf("unsigned %ld bits, %ld bytes\n", sizeof(unsigned)*CHAR_BIT,(sizeof(unsigned)*CHAR_BIT)/8);
    printf("int %ld bits, %ld bytes\n", sizeof(int) * CHAR_BIT, (sizeof(int) * CHAR_BIT)/8);
    printf("long int %ld bits, %ld bytes\n", sizeof(long) * CHAR_BIT, (sizeof(long) * CHAR_BIT)/8);
    printf("long long int %ld bits, %ld bytes\n", sizeof(long long) * CHAR_BIT, (sizeof(long long) * CHAR_BIT)/8);
    printf("float %ld bits, %ld bytes\n", sizeof(float) * CHAR_BIT, (sizeof(float) * CHAR_BIT)/8);
    printf("double %ld bits, %ld bytes\n", sizeof(double) * CHAR_BIT, (sizeof(double) * CHAR_BIT)/8);
    printf("long double %ld bits, %ld bytes\n\n", sizeof(long double) * CHAR_BIT, (sizeof(long double) * CHAR_BIT)/8);
    printf("Header u %ld bits, %ld bytes\n", sizeof(u) * CHAR_BIT, (sizeof(u) * CHAR_BIT)/8);
    printf("Header *ptr %ld bits, %ld bytes\n", sizeof(u.s.ptr) * CHAR_BIT, (sizeof(u.s.ptr) * CHAR_BIT)/8);
    printf("Header size %ld bits, %ld bytes\n", sizeof(u.s.size) * CHAR_BIT, (sizeof(u.s.size) * CHAR_BIT)/8);
    printf("Header x %ld bits, %ld bytes\n\n", sizeof(u.x) * CHAR_BIT, (sizeof(u.x) * CHAR_BIT)/8);
    printf("Hair h %ld bits, %ld bytes\n", sizeof(h) * CHAR_BIT, (sizeof(h) * CHAR_BIT)/8);
    printf("Hair *ptr %ld bits, %ld bytes\n", sizeof(h.ptr) * CHAR_BIT, (sizeof(h.ptr) * CHAR_BIT)/8);
    printf("Hair size %ld bits, %ld bytes\n", sizeof(h.size) * CHAR_BIT, (sizeof(h.size) * CHAR_BIT)/8);
    return 0;
}

:

$ ./union-limits 
char 8 bits, 1 bytes
unsigned 32 bits, 4 bytes
int 32 bits, 4 bytes
long int 64 bits, 8 bytes
long long int 64 bits, 8 bytes
float 32 bits, 4 bytes
double 64 bits, 8 bytes
long double 128 bits, 16 bytes

Header u 128 bits, 16 bytes
Header *ptr 64 bits, 8 bytes
Header size 32 bits, 4 bytes
Header x 64 bits, 8 bytes

Hair h 128 bits, 16 bytes
Hair *ptr 64 bits, 8 bytes
Hair size 32 bits, 4 bytes

As you can see, the hair has the same heading size. But for compilers that don’t do this work, it’s right to use long double as Align.

Take care, Beco.

0
source

Source: https://habr.com/ru/post/1607471/


All Articles