| Contents |

16 <stdalign.h> Macro Cho Alignment

Nếu bạn đang code thứ gì đó low-level như một memory allocator giao tiếp với OS, bạn có thể cần header này. Nhưng hầu hết dev C trải cả sự nghiệp mà chưa bao giờ dùng nó.

Alignment37 là về bội số của địa chỉ mà object có thể được lưu. Object có thể lưu ở bất kỳ địa chỉ nào? Hay phải là địa chỉ chia hết cho 2? Hay 8? Hay 16?

Tên Mô tả
alignas() Chỉ định alignment, expand thành _Alignas
alignof() Lấy alignment, expand thành _Alignof

Hai macro bổ sung sau được định nghĩa bằng 1:

__alignas_is_defined
__alignof_is_defined

Ghi chú nhanh: các alignment lớn hơn của max_align_t được gọi là overalignment và là implementation-defined.

16.1 alignas() _Alignas()

Bắt biến phải có một alignment nhất định

Synopsis

#include <stdalign.h>

alignas(type-name)
alignas(constant-expression)
_Alignas(type-name)
_Alignas(constant-expression)

Mô tả

Dùng alignment specifier này để bắt buộc alignment cho biến cụ thể. Ví dụ, ta có thể khai báo cchar, nhưng align giống như nó là int:

char alignas(int) c;

Bạn cũng có thể đặt biểu thức integer hằng vào đó. Compiler có lẽ sẽ áp limit lên giá trị mà biểu thức này có thể nhận. Lũy thừa nhỏ của 2 (1, 2, 4, 8, và 16) thường là đặt cược an toàn.

char alignas(8) c;   // align theo ranh giới 8-byte

Cho tiện, bạn cũng có thể chỉ định 0 nếu muốn alignment mặc định (như thể bạn không nói alignas() gì cả):

char alignas(0) c;   // dùng alignment mặc định cho kiểu này

Ví dụ

#include <stdalign.h>
#include <stdio.h>     // for printf()
#include <stddef.h>    // for max_align_t

int main(void)
{
    int i, j;
    char alignas(max_align_t) a, b;
    char alignas(int) c, d;
    char e, f;

    printf("i: %p\n", (void *)&i);
    printf("j: %p\n\n", (void *)&j);
    printf("a: %p\n", (void *)&a);
    printf("b: %p\n\n", (void *)&b);
    printf("c: %p\n", (void *)&c);
    printf("d: %p\n\n", (void *)&d);
    printf("e: %p\n", (void *)&e);
    printf("f: %p\n", (void *)&f);
}

Output trên hệ của tôi bên dưới. Chú ý sự khác biệt giữa các cặp giá trị.

i: 0x7ffee7dfb4cc    <-- difference of 4 bytes
j: 0x7ffee7dfb4c8

a: 0x7ffee7dfb4c0    <-- difference of 16 bytes
b: 0x7ffee7dfb4b0

c: 0x7ffee7dfb4ac    <-- difference of 4 bytes
d: 0x7ffee7dfb4a8

e: 0x7ffee7dfb4a7    <-- difference of 1 byte
f: 0x7ffee7dfb4a6

Xem thêm

alignof, max_align_t, memalignment()


16.2 alignof() _Alignof()

Lấy alignment của một kiểu

Synopsis

#include <stdalign.h>

alignof(type-name)
_Alignof(type-name)

Mô tả

Biểu thức này eval thành một giá trị kiểu size_t cho biết alignment của một kiểu cụ thể trên hệ của bạn.

Giá trị trả về

Trả về giá trị alignment, tức là địa chỉ bắt đầu của object kiểu đã cho phải ở ranh giới chia hết cho số này.

Ví dụ

In ra alignment của đủ loại kiểu khác nhau.

#include <stdalign.h>
#include <stdio.h>     // for printf()
#include <stddef.h>    // for max_align_t

struct t {
    int a;
    char b;
    float c;
};

int main(void)
{
    printf("char       : %zu\n", alignof(char));
    printf("short      : %zu\n", alignof(short));
    printf("int        : %zu\n", alignof(int));
    printf("long       : %zu\n", alignof(long));
    printf("long long  : %zu\n", alignof(long long));
    printf("double     : %zu\n", alignof(double));
    printf("long double: %zu\n", alignof(long double));
    printf("struct t   : %zu\n", alignof(struct t));
    printf("max_align_t: %zu\n", alignof(max_align_t));
}

Output trên hệ của tôi:

char       : 1
short      : 2
int        : 4
long       : 8
long long  : 8
double     : 8
long double: 16
struct t   : 16
max_align_t: 16

Xem thêm

alignas, max_align_t, memalignment()


| Contents |