473,406 Members | 2,867 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

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 4458
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_cast<int*>(&(var.b[i])) - reinterpret_cast<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_cast<int*>(&(var.b[i])) - reinterpret_cast<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_cast<int*>(&(var.b[i])) - reinterpret_cast<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_cast<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_cast<size_t> instead of reinterprete_cast<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******@kostur.net> wrote in message news:Xn******************************@207.35.177.1 34...
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_cast<int*>(&(var.b[i])) - reinterpret_cast<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_cast<int*>(&(var.b[i])) - reinterpret_cast<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_cast<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_cast<size_t> instead of reinterprete_cast<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
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) ...
9
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...
20
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...
6
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...
10
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...
44
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...
8
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
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?...
2
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...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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...
0
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,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.