Re: problem with sizeof



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
.



Relevant Pages

  • Re: Why #pragma pack() not take effect?
    ... What compiler on which platform are you using? ... maximum alignment (that is, ... You seem to actually want padding instead of packing. ... same structure as on a 64-bit platform such as HP-UX ia64. ...
    (comp.unix.programmer)
  • Re: UDT memory alignment
    ... Probably the simplest way to look at this, is instead of calling it "dword ... the alignment is such that the whole ... positioned at an alignment that is a multiple of it's length, ... they can be placed without the need for preceding padding. ...
    (microsoft.public.vb.general.discussion)
  • Re: Howto pass derived type arguments to C-Functions
    ... between the fortran compiler and its companion C compiler, ... perhaps the padding and alignment are somehow defined in that language, ...
    (comp.lang.fortran)
  • Re: Structure padding.
    ... >I need to fill in the size of padding array here so as to ... >make the entire structure size a multiple of 8. ... compiler is happy with the idea of the structure size being a multiple of ...
    (comp.lang.c)
  • Re: One for the language lawyers
    ... padding for structures. ... We can also use aligned attributes for buffer to coerce the alignment. ... These things are different on every compiler. ... I've hunted bugs when different packed/not packed options ...
    (comp.lang.c)