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
I'm confused about the print address: there are 2 bytes before buf_a.len? The address buf_a.data is at the end of the struct? Shouldn't the __buf[0] point to the buf_a.data directly?
CodePudding user response:
There is no unaccounted for space at the front of the struct
.
However, even if we remove the aligned
on __buf
, it still does alignment of the struct
length.
Unless, we add __attribute__((packed))
to the struct definition.
Here is a modified version of your code to produce a test program:
#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;
}
Here is the output of the program compiled normally:
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)
Here is the output with -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)
Here is the output with: -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)