Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > how best to get the offset of a field within a struct?

Reply
Thread Tools

how best to get the offset of a field within a struct?

 
 
funkyj
Guest
Posts: n/a
 
      02-17-2006
PROBLEM STATEMENT:
I want to calculate the byte offset of a field with a struct at
compile time without instantiating an instance of the struct at
runtime AND I want to do this in an ANSI standard compliant
fashion.

DISCUSSION:

Below is a sample program that demonstrates my solution. My questions
are:

(1) is this ANSI C compliant?
(2) is there a better way to solve this problem?


I think I'm on safe ground because casting and taking the address of
stuff does not cause memory to be accessed (i.e. pointers
dereferenced). In any event I seem to have satisfied GCC:

> cd c:/cygwin/home/fj/offset/
> make offset && ./offset
> gcc -ansi -pedantic -o offset offset.c
> MY_OFFSET(verybig_t, a) = 0x0
> MY_OFFSET(verybig_t, g) = 0x20
> MY_OFFSET(verybig_t, j) = 0x202a
> MY_OFFSET(verybig_t, p) = 0x203a
>
> Compilation finished at Fri Feb 17 11:41:58


Regards,
--jfc

================ begin sample program offset.c ================
#include <stdio.h>
typedef struct {
long a, b, c;
short e, f;
char name[13];
long g, h;
char stuff[1 << 13];
short i;
char j;
long k, l, m;
char n, o, p;
} verybig_t;

#define MY_OFFSET(type, field) ((unsigned long ) &(((type *)
0)->field))

int main(int argc, char * argv[])
{
printf("MY_OFFSET(verybig_t, a) = 0x%x\n", MY_OFFSET(verybig_t,
a));
printf("MY_OFFSET(verybig_t, g) = 0x%x\n", MY_OFFSET(verybig_t,
g));
printf("MY_OFFSET(verybig_t, j) = 0x%x\n", MY_OFFSET(verybig_t,
j));
printf("MY_OFFSET(verybig_t, p) = 0x%x\n", MY_OFFSET(verybig_t,
p));
return(0);
}

 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      02-17-2006


funkyj wrote On 02/17/06 14:44,:
> PROBLEM STATEMENT:
> I want to calculate the byte offset of a field with a struct at
> compile time without instantiating an instance of the struct at
> runtime AND I want to do this in an ANSI standard compliant
> fashion.


Use the offsetof() macro, defined in <stddef.h>.

> DISCUSSION:
>
> Below is a sample program that demonstrates my solution. My questions
> are:
>
> (1) is this ANSI C compliant?


No.

> (2) is there a better way to solve this problem?


Use the offsetof() macro, defined in <stddef.h>.

> [snipped a variant of the non-portable pre-ANSI substitute
> for the offsetof() macro, defined in <stddef.h>]


--
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
loufoque
Guest
Posts: n/a
 
      02-17-2006
funkyj a écrit :

> #define MY_OFFSET(type, field) ((unsigned long ) &(((type *)
> 0)->field))


You should cast it to uintptr_t rather than unsigned long.
 
Reply With Quote
 
funkyj
Guest
Posts: n/a
 
      02-17-2006
Thanks! Apparently I wasn't that far off. My local include files
implement it like this:

#define __offsetof(type, field) ((size_t)(&((type *)0)->field))
/* ansi.h */
#define offsetof(type, member) __offsetof(type, member) /*
stddef.h */

 
Reply With Quote
 
Clark S. Cox III
Guest
Posts: n/a
 
      02-17-2006
On 2006-02-17 14:44:30 -0500, "funkyj" <(E-Mail Removed)> said:

> PROBLEM STATEMENT:
> I want to calculate the byte offset of a field with a struct at
> compile time without instantiating an instance of the struct at
> runtime AND I want to do this in an ANSI standard compliant
> fashion.
>
> DISCUSSION:
>
> Below is a sample program that demonstrates my solution. My questions
> are:
>
> (1) is this ANSI C compliant?


No, it is not. (Dereferencing a NULL pointer leads to undefined behavior)

> (2) is there a better way to solve this problem?


Yes. You don't need to solve it, it has already been solved for you.
Just use the "offsetof" macro already provided for you by standard C.


--
Clark S. Cox, III
(E-Mail Removed)

 
Reply With Quote
 
tedu
Guest
Posts: n/a
 
      02-17-2006
Clark S. Cox III wrote:
> On 2006-02-17 14:44:30 -0500, "funkyj" <(E-Mail Removed)> said:
> > PROBLEM STATEMENT:
> > I want to calculate the byte offset of a field with a struct at
> > compile time without instantiating an instance of the struct at
> > runtime AND I want to do this in an ANSI standard compliant
> > fashion.
> > (1) is this ANSI C compliant?

>
> No, it is not. (Dereferencing a NULL pointer leads to undefined behavior)


assuming one doesn't wish to use offsetof, what potential problems
exist with the following (aside from non compatible usage)?

#define almostoffsetof(type, field, o) { \
type tmp_; \
o = &tmp_.field - &tmp_; \
}

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      02-17-2006


tedu wrote On 02/17/06 16:24,:
> Clark S. Cox III wrote:
>
>>On 2006-02-17 14:44:30 -0500, "funkyj" <(E-Mail Removed)> said:
>>
>>>PROBLEM STATEMENT:
>>> I want to calculate the byte offset of a field with a struct at
>>> compile time without instantiating an instance of the struct at
>>> runtime AND I want to do this in an ANSI standard compliant
>>> fashion.
>>> (1) is this ANSI C compliant?

>>
>>No, it is not. (Dereferencing a NULL pointer leads to undefined behavior)

>
>
> assuming one doesn't wish to use offsetof,


Why assume such a silly thing? "Assuming one doesn't
wish to use parentheses ..."

> what potential problems
> exist with the following (aside from non compatible usage)?
>
> #define almostoffsetof(type, field, o) { \
> type tmp_; \
> o = &tmp_.field - &tmp_; \
> }


How about "It doesn't work" -- does that qualify as a
"potential problem?" Sheesh ...

--
(E-Mail Removed)

 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      02-17-2006
funkyj wrote:
> Thanks! Apparently I wasn't that far off. My local include files
> implement it like this:
>
> #define __offsetof(type, field) ((size_t)(&((type *)0)->field))
> /* ansi.h */
> #define offsetof(type, member) __offsetof(type, member) /*
> stddef.h */


Just because your system implements offsetof like that does not make it
portable. In fact, if you use that method, rather than just using the
offsetof macro provided by your system, it most definitely is *not*
portable.

offsetof is provided as a standard macros specifically because it is
*impossible* to implement it portably.
--
Flash Gordon
Living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidlines and intro -
http://clc-wiki.net/wiki/Intro_to_clc
 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      02-17-2006
tedu wrote:
> Clark S. Cox III wrote:
>> On 2006-02-17 14:44:30 -0500, "funkyj" <(E-Mail Removed)> said:
>>> PROBLEM STATEMENT:
>>> I want to calculate the byte offset of a field with a struct at
>>> compile time without instantiating an instance of the struct at
>>> runtime AND I want to do this in an ANSI standard compliant
>>> fashion.
>>> (1) is this ANSI C compliant?

>> No, it is not. (Dereferencing a NULL pointer leads to undefined behavior)

>
> assuming one doesn't wish to use offsetof, what potential problems
> exist with the following (aside from non compatible usage)?
>
> #define almostoffsetof(type, field, o) { \
> type tmp_; \
> o = &tmp_.field - &tmp_; \
> }


struct tmp_ {int a; int b;} tmp_
size_t o;

....

if (flag)
almostoffsetof(tmp_, b, o);
else
almostoffsetof(tmp_, a, o);

Should show you a couple of potential problems, one of which has a
standard solution the other is rather harder to avoid.
--
Flash Gordon
Living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidlines and intro -
http://clc-wiki.net/wiki/Intro_to_clc
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      02-17-2006
"tedu" <(E-Mail Removed)> writes:
[...]
> assuming one doesn't wish to use offsetof, what potential problems
> exist with the following (aside from non compatible usage)?
>
> #define almostoffsetof(type, field, o) { \
> type tmp_; \
> o = &tmp_.field - &tmp_; \
> }


It can't be used in an expression.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Comparing offset-aware and offset-naive datetimes? Roy Smith Python 4 01-27-2013 03:17 PM
1.Enter space bar for field names and save the field.The field shoud not get saved and an alert should be there as"Space bars are not allowed" Sound Javascript 2 09-28-2006 02:43 PM
Translated Offset to Source Offset Lance Riedel XML 2 10-15-2003 03:04 PM
QUERY: field offset rules within structures Bradford Chamberlain C Programming 11 07-13-2003 06:00 PM



Advertisments