Re: C question
Jens.Toerring_at_physik.fu-berlin.de
Date: 02/13/05
- Next message: jacob navia: "Re: Making C better (by borrowing from C++)"
- Previous message: Michael Mair: "Re: C question"
- In reply to: Paul: "Re: C question"
- Next in thread: CBFalconer: "Re: C question"
- Reply: CBFalconer: "Re: C question"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
- Next message: jacob navia: "Re: Making C better (by borrowing from C++)"
- Previous message: Michael Mair: "Re: C question"
- In reply to: Paul: "Re: C question"
- Next in thread: CBFalconer: "Re: C question"
- Reply: CBFalconer: "Re: C question"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|