Reputation: 1143
I have
evnt_buff = sSpiInformation.pRxPacket;
data_to_recv = 0;
hci_hdr = (hci_hdr_t *)(evnt_buff + sizeof(btspi_hdr));
My evnt_buff is 2. Now when I typecast the above data the hci_hdr
typedef struct _hci_hdr_t
{
unsigned char ucType;
unsigned char ucOpcode;
unsigned char pad[3];
} hci_hdr_t;
hci_hdr->ucType
has a value of 0. Is this the expected behaviour?
typedef struct _btspi_hdr
{
unsigned char cmd;
unsigned short length;
unsigned char pad[2];
}btspi_hdr;
My unsigned char *evnt_buff
; is as defined . And why exacty is the sizeof()
being added here?
The above piece of code gets called from another function. The other function initializes sSpiInformation.pRxPacket
to point to a buffer whose first element is 2. This means that when
evnt_buff = sSpiInformation.pRxPacket;
is executed it becomes equal to 2.
Another thing. Since I am porting the code from one compiler to another , in the first compiler #pragma pack(1)
is used to declare all the structures. But since in my compiler I dont know the equivalent of that I simply removed that statement and initialized the structure without any packing. Could this be the issue?
Upvotes: 0
Views: 152
Reputation: 213711
It is not clear what you mean or try to achieve You say that evnt_buff
is a pointer to a character array where the first element is 2. If so, how does evnt_buff + sizeof(btspi_hdr)
make any sense whatsoever?
Anyway, the bug is post likely related to struct padding. Every compiler has an option to turn off padding, if not #pragma pack
then something else. Check the compiler documentation.
When you have questionable code like this, which relies on struct alignment, you should also add static compile-time checks to verify that no padding is enabled. One way to do so is to define a macro which yields a compiler error if the passed parameter is incorrect. For example:
#define static_assert (expr) {typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];}
(if you have a C11 compiler, a better static_assert is available by the compiler)
Then for every struct, type something like this:
static_assert (sizeof(btspi_hdr) == sizeof(cmd) +
sizeof(length) +
sizeof(pad) );
Upvotes: 0
Reputation: 70911
This line
hci_hdr = (hci_hdr_t *)(evnt_buff + sizeof(btspi_hdr));
implies that the memory pointed to by evnt_buff
consists of
btspi_hdr
hci_hdr_t
So what the above line does is assigning to hci_hdr
the address of that part of the memory pointed to by evnt_buff
which represents the hci_hdr_t
by adding the size of a btspi_hdr
to evnt_buff
.
From this I conclude hci_hdr
is declared as hci_hdr_t *
.
Upvotes: 1