Re: problem with sizeof
- From: Barry Schwarz <schwarzb@xxxxxxxxx>
- Date: Fri, 04 Jan 2008 21:15:18 -0800
On Wed, 2 Jan 2008 11:45:53 -0800, "Roman Mashak" <mrv@xxxxxxxx>
wrote:
Hello, Roman!
You wrote to All on Wed, 2 Jan 2008 09:04:22 -0800:
[skip]
RM> /* get data from USB into buffer. Data points to beginning of stream */
RM> CDC_Read(..., data, MSG_SIZE);
RM> /* parse header */
RM> USB_iobuf_common_header *hdr = (USB_iobuf_common_header *)data;
By the way, my compiler (arm-gcc 4.2.1) spits out a warning on the above
line: "cast increases required alignment of target type". Is this because
'data' and 'USB_iobuf_common_header' are of different types ?
Actually it is because they have different alignment requirements.
data is an array of char. In C, char is synonymous with byte. On
most implementations, char has no alignment (or some say it must be
aligned on a multiple of 1). As you noted in a previous message, your
structures have sizes of 4 and 8 (due to padding as others have
discussed). If the compiler is going to pad the structure out to a
multiple of 4, chances are that it will also require the structures to
be aligned on a multiple of 4. Since data is not so constrained, your
cast raises the possibility of undefined behavior whenever data is not
aligned on a multiple of 4 (which in general will happen 75% of the
time).
Unfortunately, this is not the only problem. You have no idea where
the padding is located. In your USB_iobuf_common_header, the padding
could be before size_lo or before or after size_hi. In your
USB_iobuf_i2c_header, the three padding bytes could be anywhere before
or after the last four members in any combination.
If you want to treat three elements of data as if they were the three
members of USB_iobuf_common_header, two solutions come to mind:
One is to copy the three bytes member by member (not with
memcpy) into an instance of the structure.
The other is to create defines of the form
#define common_function(x) data(x)
#define common_size_lo(x) data(x+1)
and use these in place of hdr->function, hdr->size_lo, etc.
It is also possible that your compiler has an option to not pad the
structures but that solution would not be portable.
I know in most cases casting is a wrong way and should be avoided, but I
can't see another method to extract specific field from header. Any
suggestions?
Remove del for email
.
- References:
- problem with sizeof
- From: Roman Mashak
- Re: problem with sizeof
- From: Roman Mashak
- problem with sizeof
- Prev by Date: Re: problem with sizeof
- Next by Date: Re: Suffix allowed on expressions?
- Previous by thread: Re: problem with sizeof
- Next by thread: superseded by c++?
- Index(es):
Relevant Pages
|