Re: Basic C query.
Re: Basic C query.
- Subject: Re: Basic C query.
- From: Arnab Ganguly <email@hidden>
- Date: Thu, 24 Jun 2010 21:01:05 +0530
To be more precise.I am curious to know what is the concept of behind calling ((Test *) 8)->a -8 or sometime ((Test *) 16)->a -16.Does it have any dependency with the number members present in the structure or how is it ?Also how things are to be handled in case of OS 64bit.
-R
On Thu, Jun 24, 2010 at 6:44 PM, Arnab Ganguly
<email@hidden> wrote:
Hi All,Thanks for all help and inputs.Got the idea of offsetof() .But unfortunately not clear about what is the concept of 8 and then again subtracting for 8.Like when will i do 16 and -16 etc?
Please help.
-A
On Thu, Jun 24, 2010 at 9:56 AM, Terry Lambert
<email@hidden> wrote:
On Jun 23, 2010, at 7:53 AM, Arnab Ganguly wrote:
Dear All,
Sorry for posting a basic C question.Below is the code base.
struct Test
{
int a;
int b;
};
//member offset.
int result = (((Test *) 8)->a) - 8;
I get bus error for this. I am not clear about the logic as what exactly ((Test *) 8)->a signifies here and why -8 is done.
I have copy pasted a smaller portion of the main code.Only one line written as Member offset. The above code works fine in 32bit but in 64bit I am getting issue if I can understand the above logic will be more clear as what needs to be done.
Jamison pointed out that you are dereferencing the field rather than taking the field address, and that 'Test' is not a type. I'm guessing that if you're getting a bus error, you're at least doing the type thing right in your real code.
Peter pointed you to offsetof(), which is available in c99, but not standardized before c99, so if you are using an older compiler, it's possible it won't be available, even as a compiler specific built-in prior to c99, which makes it hard to rely on.
Jens suggest fixing it by adding an &; this has the same problem as your original code, which is specifically that sizeof(struct Test) != 1, so when you do pointer math on it, you're actually not subtracting 8 bytes, you're substracting 8 * sizeof(Test) bytes, which is going to put you in negative stack space.
Rohitash gave you a correct non-c99 implementation. However, this code will not work portably with all c99 compilers. You can, if you want to play language-lawyer, interpret the c99 standard in a particular way using three clauses in combination to make it say arithmetic on a cast 0 is not legal, which permits the compiler writer to cause the compiler to go off into the weeds (the LLVM C compiler goes off into the weeds in this specific case, as one example). You can language-lawyer back for using a non-zero constant, since it isn't NULL, e.g. (to avoid structure packing issues):
#define offsetof(type, field) ((size_t)((char *)&((type *)8)->field - (char *)8))
... but some c99 compilers will probably still go off into the weeds on general "we language-lawyered in the first place because we didn't want to make it work to avoid breaking older code" principles, so why bother? Use #if and be done with it:
#if (__STDC_VERSION__ -199901L) < 0L
... work around not using a c99 compiler ...
#else
... offsetof() is defined in <stddef.h> ...
#endif
Alastair pointed out that language questions don't belong on this list, which is true. I'd argue for lenience, since it's minorly relevant to Mac OS X porting of old code that uses constructs like this to get around the lack of a portably usable offsetof() which were written prior to the last few years when c99 compilers started being generally available.
-- Terry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden