Data representation 2: Sizes and layout

Overview

Last time, we examined memory broadly, dividing it into regions called segments that hold different kinds of objects. This time, we consider memory in a more fine-grained way, investigating type sizes, alignments, and layout rules.

Primitive types

C++’s primitive values include integers, floating point numbers, and pointers. This program, sizes.cc, prints out some of their values. What do you see?

#include <cstdio>
#include "hexdump.hh"

int main() {
    char c1 = 61;
    int i1 = 61;
    float f1 = 61;
    int* p1 = &i1;

    printf("c1: %d\n", (int) c1);
    printf("i1: %d\n", i1);
    printf("f1: %g\n", f1);
    printf("p1: %p\n", p1);

    hexdump_object(c1);
    hexdump_object(i1);
    hexdump_object(f1);
    hexdump_object(p1);
}

Primitive type observations

Sizes and sizeof

Sizes of primitive types

Type

Size

char

1

short

2

int

4

long

8

long long

8

float

4

double

8

long double

16

T*

8

Abstract machine and hardware machine

Standard sizes of primitive types

Type

x86-64 Linux size

Standard size

char

1

1

short

2

≥1

int

4

sizeof(short)

long

8

sizeof(int)

long long

8

sizeof(long)

float

4

≥4 (probably)

double

8

sizeof(float), ≥8 (probably)

long double

16

sizeof(double)

T*

8

N/A

Variant types

Objects in memory

Compound types (collections)

Compound type example

#include <cstdio>
#include "hexdump.hh"

int main() {
    int a[2] = {61, 62};

    union {
        int a;
        int b;
        char c;
        char d;
    } u;
    u.a = 61;

    struct {
        int a;
        int b;
        char c;
        char d;
    } s = {61, 62, 63, 64};

    hexdump_object(a);
    hexdump_object(u);
    hexdump_object(s);
}

Array rule

addressof(a[I]) = addressof(a) + I*sizeof(T)
sizeof(a) = N*sizeof(T)

Union rule

addressof(u.mI) = addressof(u)
sizeof(u) = maxI sizeof(TI)

Struct rule (?)

addressof(s.c1) = addressof(s)
For I>1, addressof(s.mI) = addressof(s.mI-1) + sizeof(TI-1) (?)
sizeof(s) = ∑I sizeof(TI) (?)

Alignment

Alignments of primitive types

Type

Alignment

char

1

short

2

int

4

long

8

long long

8

float

4

double

8

long double

16

T*

8

Alignments of compound types

Struct rule


  1. See, for example, the C++ standard 6.8.1.2 [basic.types.general]: “the underlying bytes making up [any simple] object can be copied into an array of char, unsigned char, or std::byte (17.2.1). If the content of that array is copied back into the object, the object shall subsequently hold its original value.” ↩︎