473,883 Members | 2,621 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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

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(veryb ig_t, a) = 0x0
MY_OFFSET(veryb ig_t, g) = 0x20
MY_OFFSET(veryb ig_t, j) = 0x202a
MY_OFFSET(veryb ig_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_OFFS ET(verybig_t, a) = 0x%x\n", MY_OFFSET(veryb ig_t,
a));
printf("MY_OFFS ET(verybig_t, g) = 0x%x\n", MY_OFFSET(veryb ig_t,
g));
printf("MY_OFFS ET(verybig_t, j) = 0x%x\n", MY_OFFSET(veryb ig_t,
j));
printf("MY_OFFS ET(verybig_t, p) = 0x%x\n", MY_OFFSET(veryb ig_t,
p));
return(0);
}

Feb 17 '06
24 10382

Keith Thompson wrote:
"tmp123" <tm****@menta.n et> writes:
Keith Thompson wrote:
"funkyj" <fu****@gmail.c om> writes:
> 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.

There is no portable way to implement offsetof in standard C.


I suposse the following two methods are not standard due to the pointer
conversions. But I do not in how many points they break the rules:
...
static void *foo;
#define offsetof1(x,a) ( (char *)&( ((x *)foo)->a ) - (char *)foo )
#define offsetof2(x,a) ( *(char *) ( &(((x *)foo)->a) ) )


foo is a static pointer object; it's therefore initialized to NULL.
(Since it's not const, you could mess it up by assigning a value to
foo.)

Both are similar to the common definition of offset(), except that
they use foo rather than a literal 0. Both dereference a null pointer


Sorry, I've not been clear enough. Please, see at init part of the main
function (I repeat it because it has been snipped):

/* init */
int i;
foo=malloc(256) ;
for(i=0;i<256;i ++) ((char *)foo)[i]=i;

Moreover, method 2 doesn't uses pointer substraction.

Kind regards.

Feb 18 '06 #21
"tmp123" <tm****@menta.n et> writes:
Keith Thompson wrote:
"tmp123" <tm****@menta.n et> writes:
> Keith Thompson wrote:
>> "funkyj" <fu****@gmail.c om> writes:
>> > 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.
>>
>> There is no portable way to implement offsetof in standard C.
>
> I suposse the following two methods are not standard due to the pointer
> conversions. But I do not in how many points they break the rules:
>...
> static void *foo;
> #define offsetof1(x,a) ( (char *)&( ((x *)foo)->a ) - (char *)foo )
> #define offsetof2(x,a) ( *(char *) ( &(((x *)foo)->a) ) )


foo is a static pointer object; it's therefore initialized to NULL.
(Since it's not const, you could mess it up by assigning a value to
foo.)

Both are similar to the common definition of offset(), except that
they use foo rather than a literal 0. Both dereference a null pointer


Sorry, I've not been clear enough. Please, see at init part of the main
function (I repeat it because it has been snipped):

/* init */
int i;
foo=malloc(256) ;
for(i=0;i<256;i ++) ((char *)foo)[i]=i;

Moreover, method 2 doesn't uses pointer substraction.


Sorry, I didn't read carefully enough.

Both offsetof1 and offsetof2 depend on the existence of an object
"foo" (used to provide a valid address, where the usual implementation
uses a null pointer). offsetof1 invokes undefined behavior if the
offset is greater than 255 bytes; offset2 depends on the stored value,
and won't work at all for offsets greater than 255. For offsetof1 to
work in the general case, you'd need foo to be as large as the largest
possible struct; offsetof2 works only with 1-byte array elements (and
even then you'd want unsigned char rather than char).

I think offsetof1 is probably about as close as you can get to a
portable implementation, but every compiler supports a non-portable
implementation that doesn't have the same drawbacks.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <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.
Feb 18 '06 #22
The suspicion that I was doing something fishy was what let me to post
my question. Your summary above touches on the key points.

The C standard authors put offsetof() in the standard library so that
the language need not provide a portable way of doing this by hand.
This language design choice provides the user with the needed
functionality (i.e. offsetof()) while giving the compiler writer more
latitude.

Thanks!
--jfc

Feb 21 '06 #23
"funkyj" <fu****@gmail.c om> writes:
The suspicion that I was doing something fishy was what let me to post
my question. Your summary above touches on the key points.
What summary? There's nothing "above", and the article to which you
replied isn't available on my news server.

Please please *please* read <http://cfaj.freeshell. org/google/>.
The C standard authors put offsetof() in the standard library so that
the language need not provide a portable way of doing this by hand.
This language design choice provides the user with the needed
functionality (i.e. offsetof()) while giving the compiler writer more
latitude.


Correct.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <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.
Feb 21 '06 #24
On Fri, 17 Feb 2006 22:22:13 +0000, Flash Gordon
<sp**@flash-gordon.me.uk> wrote:
tedu wrote:
#define almostoffsetof( type, field, o) { \
type tmp_; \
o = &tmp_.field - &tmp_; \
}


later corrected to (char*)&tmp_.fi eld - (char*)&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.


That won't compile; first you're missing a semicolon, then (in C) tmp_
is not a typename as required by both his almostoffsetof( ) and
standard offsetof(). You could either use struct tmp_ for the
typename, or change the struct declaration to a typedef, and either
way I see no problem.

- David.Thompson1 at worldnet.att.ne t
Feb 27 '06 #25

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
3484
by: Bradford Chamberlain | last post by:
I work a lot with multidimensional arrays of dynamic size in C, implementing them using a single-dimensional C array and the appropriate multipliers and offsets to index into it appropriately. I tend to iterate over subsets of these arrays by walking a pointer and an offset per dimension across their dimensions. I've found that this tends to result in more performance in a portable manner than doing explicit indexing calculations and...
1
4751
by: mrhicks | last post by:
Hello all, I am trying to keep my coding easy for everyone to use. I have some ARINC data that need to go out which 12 Bytes long. The first byte is the command word, the next 10 bytes represent 40 devices in the system with four command that can be issue per device. So within the each byte of the 10 bytes a command comprises 4 device. The last byte is a send flag. I first tried creating a struct like the following...
0
291
by: lawrence | last post by:
How to deal with pointer field in struct in idl So that C# can call C++ COM? e.g. in C++ COM Server IDL: typedef struct { long *xPos; long yPos; } MYPOINT;
1
2250
by: J | last post by:
I'm interfacing with a C api (via Interop) which uses the following typedef struct... typedef struct _columnflags { BYTE bNoUpdate : 1; BYTE bSetToNull : 1; BYTE bDefault : 1; } columnflags;
1
1253
by: rouble | last post by:
Hi All, How do I verify if a field within an ADODB.Recordset is NULL ? I have tried the following two methods that I could think of: 1. If Not IsNothing(rs("fieldname")) Then something = Int32.Parse(rs("fieldname").Value()) End If
2
2759
by: ice88 | last post by:
i have problem in define struct within struct struct student_detail { int id; string name; }; struct subject_detail
2
3850
by: zufie | last post by:
How would I transfer the values from my WorkPhone field to my CellPhone field within the same table IBCCP Referral? Thanks!, John
0
9933
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
11125
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10734
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10836
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10407
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9568
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5794
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5982
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3230
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.