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


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):%dn",  &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。数据是在结构的末尾吗?__buf[0]不应该指向buf_a。直接数据?

struct前面没有未占用的空间。

然而,即使我们去掉__buf上的aligned,它仍然对struct的长度进行对齐。

除非将__attribute__((packed))添加到struct定义中。


这是您的代码的修改版本,以产生一个测试程序:

#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: %sn",sym);
printf("  bufp %pn",bufp);
SHOWP(data);
SHOWI(len);
SHOWI(size);
SHOWP(__buf);
}
int
main(void)
{
printf("sizeof=%zun",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)

最新更新