Re: C question

Jens.Toerring_at_physik.fu-berlin.de
Date: 02/13/05


Date: 13 Feb 2005 13:04:04 GMT

Paul <paul@rtfm.org> wrote:
> I should better explain what I am trying to do with this C code.

> I have some data being stored in a buffer that I have previously
> malloc()'d. The data contains cluster values for the FAT (file allocation
> table)

> On an intel based system (which i am writing the C code under). The
> endianess
> is fine. The data is stored in a manner that no translation/conversion
> is necessary. Microsoft give this example in C on how to access the data in
> the buffer
> (taken from their document on the FAT32 spec)

> FAT32ClusEntryVal = (*((unsigned long *) &Buffer[ThisFATEntOffset]));

> What does the (*((unsigned long *) mean? Could someone explain this.

> The &Buffer[ThisFATEntOffset] is pretty self explanitory. The cast to the
> left
> of it confuses me.

Think about what type '&Buffer[ThisFATEntOffset]' has. It's the address
of a char. So if you would dereference that directly you would get the
value of the single char that's stored at that address and converted
to the type you have on the left hand side of the assignment. But you
don't want that char value, you want sizeof(unsigned long) chars
(probably 4 on the platform it was written for), starting at that
address and taken together as an unsigned long value. For that reaso
you must tell the compiler that '&Buffer[ThisFATEntOffset]' should be
treated as if it would be not a char pointer but a pointer to unsigned
long:

       (unsigned long *) &Buffer[ThisFATEntOffset]

When you now dereference this by putting the asterik in front of it
then the code assumes that the compiler will give you the value stored
in the (probably 4) bytes at that offset, interpreted as an unsigned
long.

The problem with this is that while it probably will run without
problems on an Intel machine it may fail on other architectures. And
that's due to alignment issues. On several non-Intel architectures
an (unsigned) long can only start at addresses that can be divided
by either 2 or 4 (or possibly 8). On the other hand, a char array
can start at any address. Therefore, '&Buffer[ThisFATEntOffset]' may
be at an address at which an unsigned long can't start and when you
force the machine to try anyway by casting you get a bus error. That's
why people have been telling you not to do that but use memcpy()
instead. Using memcpy() is the only way where you are guaranteed that
it will work correctly on all machines. The programmers at Microsoft
of course don't have to care since all they support are Intel-like
archtitectures, so they can get away with doing it.

                                    Regards, Jens

-- 
  \   Jens Thoms Toerring  ___  Jens.Toerring@physik.fu-berlin.de
   \__________________________  http://www.toerring.de


Relevant Pages

  • Re: Sizeof query
    ... object can be treated as an array of char, at least not in so many ... � Except for bit-fields, ... Note that it talks about *copying* the value into an array of unsigned ... The key point in putting together the inference is the memcpy() ...
    (comp.lang.c)
  • Re: Sizeof query
    ... object can be treated as an array of char, at least not in so many ... Note that it talks about *copying* the value into an array of unsigned ... The key point in putting together the inference is the memcpy() ... explicitly stated as being the only way of doing it, implies that ...
    (comp.lang.c)
  • Re: Alignment problem (maybe)
    ... so memcpy should work correctly... ... dword ... to the data structure was pointing within a memory buffer, ... So, when I was writing the values char by char, there were no problems ...
    (comp.os.linux.development.apps)
  • Re: help understanding character arrays
    ... the standard functions like 'memcpy' and 'memmove' live. ... what you get when the object 'mychar' "decays" to a pointer to its ... first element: a pointer to char. ... The address of the array is the same as the address of its first ...
    (comp.lang.c)
  • Re: Alignment problem (maybe)
    ... so memcpy should work correctly... ... dword ... to the data structure was pointing within a memory buffer, ... So, when I was writing the values char by char, there were no problems ...
    (comp.os.linux.development.apps)

Loading