我想使用该 struct 来存储一些数据,然后通过DMA传输它.然而,外围设备的细节要求沿着4字节边界对齐 struct 的初始地址.我不明白为什么在不同的地方使用alignment属性会导致压缩 struct 的大小被调整1个字节.

我写了一个简单的例子来说明这种情况.

#include <stdio.h>
#include "stdint.h"

// Version with aligned attribute
struct packet_v1 
{
    uint8_t uid;
    uint8_t flag;
    uint8_t comm;
    uint32_t a;
    
} __attribute__((packed, aligned(4)));

// Version without alignment 
struct packet_v2
{
    uint8_t uid;
    uint8_t flag;
    uint8_t comm;
    uint32_t a;
    
} __attribute__((packed));


struct packet_v1 pkt1;
struct packet_v2 pkt2 __attribute__((aligned(4)));


int main()
{
    printf("Align v1: %lu, size: %lu\r\n", (uintptr_t)&pkt1 % 4, sizeof(pkt1));
    printf("Align v2: %lu, size: %lu\r\n", (uintptr_t)&pkt2 % 4, sizeof(pkt2));
    
    return 0;
}

输出:

Align v1: 0, size: 8
Align v2: 0, size: 7

推荐答案

struct_v1的结尾有一个填充字节,这样 struct 数组的每个元素都与4字节的边界对齐,这是aligned(4)所要求的.

struct_v2没有填充字节,这样一个 struct 数组将尽可能紧密地打包在一起.不需要将每个数组元素对齐相同.

C++相关问答推荐

char为16位且Short也为16位的c环境合法吗

漏洞仅出现在FreeBSD上,但在Windows、Linux和MacOS上运行得非常好

我可以动态分配具有空类型函数的矩阵吗?

为什么已经设置的值在C中被重置为for循环条件中的新值?

在C语言中使用scanf()时我无法理解的警告

如何设置指针指向在函数中初始化的复合文字中的整数?

C:二进制搜索和二进制插入

Ruby C Api处理异常

错误:包含文件时类型名称未知

将 struct 传递给函数

GTK3按钮信号错误

类型定义 struct 与简单的类型定义 struct

通过k&;r语法的c声明无效

`预期说明符-限定符-列表在‘(三元运算符中的’token`‘之前

将非连续物理内存映射到用户空间

为什么GCC不能在 struct 初始值设定项中以sizeof作为条件的三进制中处理复合文字的编译时求值?

GCC认为这是一个VLA是对的吗?

指向返回 struct 成员的指针,安全吗?

函数指针作为函数参数 - 应该使用 const 吗?

(GNU+Linux) 多个线程同时调用malloc()