结构中长度为零的对齐数组

aligned arrays of length zero in struct

struct net_buf_simple {
    /** Pointer to the start of data in the buffer. */
    u8_t *data;
    /** Length of the data behind the data pointer. */
    u16_t len;
    /** Amount of data that this buffer can store. */
    u16_t size;
    u8_t __buf[0] __attribute__ ((aligned(4)));
    /** Start of the data storage. Not to be accessed directly
     *  (the data pointer should be used instead).
     */
};

int main()
{
    struct net_buf_simple buf_a;
    uint8_t array[4];
    buf_a.data = array;
    
    printf("buf_a:%p, data:%p, len:%p, size:%p, __buf:%p  sizeof(int):%d\n",  &buf_a, buf_a.data, &buf_a.len, &buf_a.size, buf_a.__buf, sizeof(int));

    return 0;
}

buf_a:0x7ffc7a0f7930, data:0x555cd091e740, len:0x7ffc7a0f7938, size:0x7ffc7a0f793a, __buf:0x7ffc7a0f793c  sizeof(int):4

我对打印地址感到困惑:buf_a.len之前有2个字节?地址 buf_a.data 在结构的末尾? __buf[0] 不应该直接指向 buf_a.data 吗?

struct前面space没有没有下落。

然而,即使我们删除 __buf 上的 aligned,它仍然会对齐 struct 长度。

除非,我们在结构定义中添加__attribute__((packed))


这是您的代码的修改版本,用于生成测试程序:

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

typedef unsigned char u8_t;
typedef unsigned short u16_t;

typedef struct net_buf_simple {
    /** Pointer to the start of data in the buffer. */
    u8_t *data;

    /** Length of the data behind the data pointer. */
    u16_t len;

    /** Amount of data that this buffer can store. */
    u16_t size;

#if NOALIGN
    u8_t __buf[0];
#else
    u8_t __buf[0] __attribute__ ((aligned(4)));
#endif
    /** Start of the data storage. Not to be accessed directly
     *  (the data pointer should be used instead).
     */
}
#if PACKED
__attribute__((packed))
#endif
bufsimp;

#define SHOWP(_sym) \
    printf("  " #_sym " ptr=%p off=%zu (offsetof %zu, width %zu)\n", \
        bufp->_sym,(char *) bufp->_sym - (char *) bufp, \
        offsetof(bufsimp,_sym),sizeof(bufp->_sym))

#define SHOWI(_sym) \
    printf("  " #_sym " val=%u (offsetof %zu, width %zu)\n", \
        bufp->_sym, \
        offsetof(bufsimp,_sym),sizeof(bufp->_sym))

bufsimp *
newbuf(int cap)
{

    bufsimp *bufp = malloc(sizeof(bufsimp) + cap);

    bufp->data = bufp->__buf;
    bufp->size = cap;
    bufp->len = 0;

    return bufp;
}

void
showbuf(bufsimp *bufp,const char *sym)
{
    printf("showbuf: %s\n",sym);
    printf("  bufp %p\n",bufp);
    SHOWP(data);
    SHOWI(len);
    SHOWI(size);
    SHOWP(__buf);
}

int
main(void)
{

    printf("sizeof=%zu\n",sizeof(bufsimp));

    bufsimp *buf_a = newbuf(4);
    showbuf(buf_a,"buf_a");

#if HAVEB
    bufsimp *buf_b = newbuf(16);
    showbuf(buf_b,"buf_b");
#endif

    return 0;
}

下面是程序正常编译后的输出:

sizeof=16
showbuf: buf_a
  bufp 0x21f4270
  data ptr=0x21f427c off=12 (offsetof 0, width 8)
  len val=0 (offsetof 8, width 2)
  size val=4 (offsetof 10, width 2)
  __buf ptr=0x21f427c off=12 (offsetof 12, width 0)

这是 -DNOALIGN 的输出:

sizeof=16
showbuf: buf_a
  bufp 0x16e1270
  data ptr=0x16e127c off=12 (offsetof 0, width 8)
  len val=0 (offsetof 8, width 2)
  size val=4 (offsetof 10, width 2)
  __buf ptr=0x16e127c off=12 (offsetof 12, width 0)

这是输出:-DNOALIGN -DPACKED:

sizeof=12
showbuf: buf_a
  bufp 0xd09270
  data ptr=0xd0927c off=12 (offsetof 0, width 8)
  len val=0 (offsetof 8, width 2)
  size val=4 (offsetof 10, width 2)
  __buf ptr=0xd0927c off=12 (offsetof 12, width 0)