473,796 Members | 2,601 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Replacement for offsetof

Consider the following definition:

typedef struct {
int a;
int b[100];
} s;

Now I have a function

void f (int i) { ... }

which needs to calculate the offset within s of b[i].

I used to use the offsetof macro for this purpose:

offsetof (s, b[i])

For most compiler environments offsetof is defined as a macro as follows
in stddef.h:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

and in these cases my function works as I expected..

However, I now have a new compiler which uses a built-in function instead of this macro.
A error message is generated at compile time for my use of offsetof because
this built-in function requires that the second parameter of offsetof is a
compile-time constant. (I understand that there is some discussion about
the exact wording and interpretation of the standard with respect to the
constant requirement for offsetof.)

I have two questions, a theoretical and a practical one.

Why does the standard impose this limitation to offsetof?
It seems that there is a need to compute offsets that are not compile-time constants.

What is the best way to replace offsetof (s, b[i]) in such a way that the result is
defined according to the C++ standard?
I understand that the result of the usual macro is not really defined because
a) address 0 does not necessarily have the value 0 and
b) type casting an address to size_t is not necessary well defined in all environments.

Regards,
Fred.Zwarts.
Mar 2 '06 #1
7 4538
Fred Zwarts wrote:
Consider the following definition:

typedef struct {
int a;
int b[100];
} s;
In C++, it is preferred to do:
struct s {
int a;
int b[100];
};
Now I have a function

void f (int i) { ... }

which needs to calculate the offset within s of b[i].


Why?

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 2 '06 #2

"Ben Pope" <be************ ***@gmail.com> wrote in message news:44******** **************@ taz.nntpserver. com...
Fred Zwarts wrote:
Consider the following definition:

typedef struct {
int a;
int b[100];
} s;


In C++, it is preferred to do:
struct s {
int a;
int b[100];
};
Now I have a function

void f (int i) { ... }

which needs to calculate the offset within s of b[i].


Why?


Because the result must be added to a base address to find the address of a hardware register.

Fred.Zwarts.
Mar 2 '06 #3
Fred Zwarts wrote:
"Ben Pope" <be************ ***@gmail.com> wrote in message news:44******** **************@ taz.nntpserver. com...
Fred Zwarts wrote:
Consider the following definition:

typedef struct {
int a;
int b[100];
} s;

In C++, it is preferred to do:
struct s {
int a;
int b[100];
};
Now I have a function

void f (int i) { ... }

which needs to calculate the offset within s of b[i].

Why?


Because the result must be added to a base address to find the address of a hardware register.


s var;
reinterpret_cas t<int*>(&(var. b[i])) - reinterpret_cas t<int*>(&var)

Assuming int is the word size of your architecture, or at least the size
of your hardware registers.

It's not nice, but obviously portability is not a factor.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 2 '06 #4
Ben Pope <be************ ***@gmail.com> wrote in
news:44******** **************@ taz.nntpserver. com:
Fred Zwarts wrote:
"Ben Pope" <be************ ***@gmail.com> wrote in message
news:44******** **************@ taz.nntpserver. com...
Fred Zwarts wrote:
Consider the following definition:

typedef struct {
int a;
int b[100];
} s;
In C++, it is preferred to do:
struct s {
int a;
int b[100];
};

Now I have a function

void f (int i) { ... }

which needs to calculate the offset within s of b[i].
Why?


Because the result must be added to a base address to find the
address of a hardware register.


s var;
reinterpret_cas t<int*>(&(var. b[i])) - reinterpret_cas t<int*>(&var)

Assuming int is the word size of your architecture, or at least the
size of your hardware registers.

It's not nice, but obviously portability is not a factor.


Or how about:

offsetof(s, b) + (i * sizeof(b[0]))

Determine the offset of the array b within the struct, then add the index
distance into b.
Mar 2 '06 #5

"Ben Pope" <be************ ***@gmail.com> wrote in message news:44******** **************@ taz.nntpserver. com...
Fred Zwarts wrote:
"Ben Pope" <be************ ***@gmail.com> wrote in message news:44******** **************@ taz.nntpserver. com...
Fred Zwarts wrote:
Consider the following definition:

typedef struct {
int a;
int b[100];
} s;
In C++, it is preferred to do:
struct s {
int a;
int b[100];
};

Now I have a function

void f (int i) { ... }

which needs to calculate the offset within s of b[i].
Why?

Because the result must be added to a base address to find the address of a hardware register.


s var;


This allocates a variable from the stack, which could in some cases consume quite some memory.
(The type s is just an example. The real world structs can be much more complex and much larger.
VME memory can be quite large.)
Is there a way to calculate the offset without allocating memory.
reinterpret_cas t<int*>(&(var. b[i])) - reinterpret_cas t<int*>(&var)
I wonder whether the address arithmetic is correct.
You subtract two int* addresses.
Shouldn't you subtract two integers?
Probably you meant reinterprete_ca st<int>.
Assuming int is the word size of your architecture, or at least the size
of your hardware registers.

It's not nice, but obviously portability is not a factor.


As a matter of fact, portability is a factor.
The code is used for access to VME devices.
The code is used on different processors with different VME interfaces
(and different compilers).
Probably reinterprete_ca st<size_t> instead of reinterprete_ca st<int> will
already be more general.

But I wonder what the general solution is
with a well defined behavior according to the C++ standard.

Fred.Zwarts.
Mar 2 '06 #6

"Andre Kostur" <nn******@kostu r.net> wrote in message news:Xn******** *************** *******@207.35. 177.134...
Ben Pope <be************ ***@gmail.com> wrote in
news:44******** **************@ taz.nntpserver. com:
Fred Zwarts wrote:
"Ben Pope" <be************ ***@gmail.com> wrote in message
news:44******** **************@ taz.nntpserver. com...
Fred Zwarts wrote:
> Consider the following definition:
>
> typedef struct {
> int a;
> int b[100];
> } s;
In C++, it is preferred to do:
struct s {
int a;
int b[100];
};

> Now I have a function
>
> void f (int i) { ... }
>
> which needs to calculate the offset within s of b[i].
Why?


Because the result must be added to a base address to find the
address of a hardware register.


s var;
reinterpret_cas t<int*>(&(var. b[i])) - reinterpret_cas t<int*>(&var)

Assuming int is the word size of your architecture, or at least the
size of your hardware registers.

It's not nice, but obviously portability is not a factor.


Or how about:

offsetof(s, b) + (i * sizeof(b[0]))

Determine the offset of the array b within the struct, then add the index
distance into b.


Thanks, that seems to be a portable solution in this simple case.
But now suppose b is defined as
int b[sizeA][sizeB][SizeC];
Of course I can write out the complete indexing arithmetic to get
the offset of b[i][j][k].
The nice thing of the old offsetof behavior was that the compiler
did it for me.
I am looking for a macro which can easily replace offsetof.

Fred.Zwarts.
Mar 2 '06 #7
Fred Zwarts wrote:
"Ben Pope" <be************ ***@gmail.com> wrote in message news:44******** **************@ taz.nntpserver. com...

s var;
This allocates a variable from the stack, which could in some cases consume quite some memory.
(The type s is just an example. The real world structs can be much more complex and much larger.
VME memory can be quite large.)
Is there a way to calculate the offset without allocating memory.


Understood. I assumed you'd do the arithmetic on an already allocated
struct, or overlay a struct over your registers with a placement new
(neither of which would necessarily require an allocation).
reinterpret_cas t<int*>(&(var. b[i])) - reinterpret_cas t<int*>(&var)


I wonder whether the address arithmetic is correct.
You subtract two int* addresses.
Shouldn't you subtract two integers?
Probably you meant reinterprete_ca st<int>.


Nope. I take advantage of pointer arithmetic. This gives you the
offset in sizeof(int) steps.
Assuming int is the word size of your architecture, or at least the size
of your hardware registers.

It's not nice, but obviously portability is not a factor.


As a matter of fact, portability is a factor.


OK, but if it's mapped to registers, I figured it would be platform
specific.
The code is used for access to VME devices.
The code is used on different processors with different VME interfaces
(and different compilers).
Probably reinterprete_ca st<size_t> instead of reinterprete_ca st<int> will
already be more general.
Why? size_t is just as variable as int, or indeed int*.
But I wonder what the general solution is
with a well defined behavior according to the C++ standard.


The behaviour I describe is well defined. It's just specific to the
architecture, or more specifically, the size of int. It's just as
dependant on the architecture as the struct itself.

Andre Kostur has a solution that will work for you if you don't already
have a struct in existence or is not accessible.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 2 '06 #8

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

Similar topics

5
6347
by: Hiroki Horiuchi | last post by:
Hello. I wrote a program, but g++ warns a.c:11: warning: invalid access to non-static data member `A::y' of NULL object a.c:11: warning: (perhaps the `offsetof' macro was used incorrectly) The program is like below. class A {
9
2970
by: Exits Funnel | last post by:
Consider this code which is a very trimmed down version of some I've inherited and am trying to port from windows to g++: //Begin test1.cpp class foo { int i; int j; }; class bar { bar (int foo::* dataMember) :offsetof (foo, *dataMember) //Call this Line (A)
20
6487
by: Alejo | last post by:
Hello, My implementation does not define offsetof, so I have designed a little program that 'attempts' to find the relative position of a member in its structure. It just does not work. Could I get some pointers on what I am doing wrong (apart from being coding so late at night). #include <stdlib.h>
6
2203
by: Arthur J. O'Dwyer | last post by:
As far as I know, C89/C90 did not contain the now-standard offsetof() macro. Did C89 mandate that structs had to have a consistent layout? For example, consider the typical layout of the following structure: struct weird { int x; /* sizeof(int)==4 here */
10
3415
by: Mark A. Odell | last post by:
Is there a way to obtain the size of a struct element based only upon its offset within the struct? I seem unable to figure out a way to do this (short of comparing every element's offset with <offset>). What I would like to do is create an API something like this: #include <stddef.h> struct MemMap { unsigned char apple; // 8 bits on my platform
44
3755
by: Simon Morgan | last post by:
Hi, Can somebody please help me grok the offsetof() macro? I've found an explanation on http://www.embedded.com/shared/printableArticle.jhtml?articleID=18312031 but I'm afraid it still doesn't make sense to me. The sticking point seems to be:
8
5869
by: Pawel | last post by:
Hallo group members. //p1.cpp #include <stdio.h> #include <linux/stddef.h> struct Person { int m_age; char* m_name; };
11
2433
by: Kavya | last post by:
offsetof(T,m) (size_t)&(((T*)0)->m) Why do we always start from 0 in this macro to access the offset of structure or union. Does standard guarantees that structure and union reside at address 0? If yes, then what if I have two or more structures. How can they reside at same address?.
2
3929
by: Imre | last post by:
Hi I know that offsetof is basically a C leftover, and only works for POD types, not classes, so it is recommended that I use pointers to members instead. However, I have a problem where I don't see how I should use pointers to members. Basically, I know how to get a member if I have an object and a pointer-to-member (obj.*ptr instead of obj + offset), but I don't know how to do the opposite: getting the object from a member address and...
0
9685
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
10237
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
10187
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
10018
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
6795
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5446
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
5578
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3735
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2928
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.