473,326 Members | 2,104 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,326 software developers and data experts.

Trouble with offsetof

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)
{
// int i = offsetof (foo, *dataMember); //Call this Line (B)
}
};
//End test1.cpp

when I try to compile test1.cpp with g++, the compiler has this to say:

test2.cpp: In constructor `bar::bar(int foo::*)':
test2.cpp:6: syntax error before `;' token

A couple of questions then:

(1) Should the compiler complain? I don't have much experience with
using the 'pointer to data member' stuff, but based on the research I've
just done on the net, the code seems reasonable.

(2) If I move the call from the initializer list to the ctor body by
commenting out line (A) and uncommenting line (B), the compiler error
becomes:

test2.cpp: In constructor `bar::bar(int foo::*)':
test2.cpp:8: syntax error before `;' token
test2.cpp:8: declaration of `dataMember' shadows a parameter
test2.cpp:8: syntax error before `;' token

So, it seems the original problem persists which is reasonable but now
there's this additional shadowing issue. It's not clear to me what
parameer 'dataMember' is shadowing here? If anyone could explain this
to me it would be great.

Thanks in advance for any feedback!

-exits

Jul 22 '05 #1
9 2923
"Exits Funnel" <ex***************@yahoo.com> wrote...
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)
{
// int i = offsetof (foo, *dataMember); //Call this Line (B)
}
};
//End test1.cpp

when I try to compile test1.cpp with g++, the compiler has this to say:

test2.cpp: In constructor `bar::bar(int foo::*)':
test2.cpp:6: syntax error before `;' token

A couple of questions then:

(1) Should the compiler complain? I don't have much experience with using
the 'pointer to data member' stuff, but based on the research I've just
done on the net, the code seems reasonable.

(2) If I move the call from the initializer list to the ctor body by
commenting out line (A) and uncommenting line (B), the compiler error
becomes:

test2.cpp: In constructor `bar::bar(int foo::*)':
test2.cpp:8: syntax error before `;' token
test2.cpp:8: declaration of `dataMember' shadows a parameter
test2.cpp:8: syntax error before `;' token

So, it seems the original problem persists which is reasonable but now
there's this additional shadowing issue. It's not clear to me what
parameer 'dataMember' is shadowing here? If anyone could explain this to
me it would be great.


'offsetof' is reserved and defined only when used with POD. Your class
is not POD, so using 'offsetof' with it is essentially prohibited.

Use pointers to members, if you have to, but you'll probably be better off
if you rewrite the algorithm that was written to require 'offsetof'.

As to your particular code, 'offsetof' is a macro that usually expands into
a constant integral expression. What is the constant integral expression
doing in the initialiser list of that constructor? It's like writing

class bar {
bar(int blah) : 42 {}
};

What's the "42" for? What are you trying to do with it?

Victor
Jul 22 '05 #2
> 'offsetof' is reserved and defined only when used with POD. Your
class
is not POD, so using 'offsetof' with it is essentially prohibited.


That was my first reaction too, but it's incorrect. He's calling
offsetof _in_ the ctor of bar (and having an explicit ctor means bar
isn't a POD type), but the argument he's passing is foo -- and foo IS a
POD type.

The problem is that he's passing a _pointer_ to a member where offsetof
expects the _name_ of the member. In C++, offsetof is really more
tolerated than fully supported -- it doesn't work with new-fangled
things like pointers to members.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 22 '05 #3
Thanks for taking the time to reply, Victor.
'offsetof' is reserved and defined only when used with POD. Your class
is not POD, so using 'offsetof' with it is essentially prohibited.
This is good to know; I couldn't find much info on offsetof anywhere.
It's not clear to me though what makes foo not a POD. Is it just that
the members are private? I just modified the code to make them public
but I get the same error.

Use pointers to members, if you have to, but you'll probably be better off
if you rewrite the algorithm that was written to require 'offsetof'.
Hopefully, I'll be able to go this route but it's ALOT of code and I'd
like to get it running sooner rather than later.

As to your particular code, 'offsetof' is a macro that usually expands into
a constant integral expression. What is the constant integral expression
doing in the initialiser list of that constructor?
Good point. Actually, I always try to trim as much of the code away as
possible while still retaining the error before posting to USENET.
Maybe I went a bit too far this time :) The actual code was, of course,
something like this:

bar (int foo::* dataMember)
:myVal (offsetof (foo, *dataMember)) //Call this Line (A)

-exits


Jul 22 '05 #4
"Jerry Coffin" <jc*****@taeus.com> wrote...
'offsetof' is reserved and defined only when used with POD. Your

class
is not POD, so using 'offsetof' with it is essentially prohibited.


That was my first reaction too, but it's incorrect. He's calling
offsetof _in_ the ctor of bar (and having an explicit ctor means bar
isn't a POD type), but the argument he's passing is foo -- and foo IS a
POD type.


How is it POD if it's a class and the members are private?

V
Jul 22 '05 #5
"Exits Funnel" <ex***************@yahoo.com> wrote...
[...] Actually, I always try to trim as much of the code away as possible
while still retaining the error before posting to USENET. Maybe I went a
bit too far this time :) The actual code was, of course, something like
this:

bar (int foo::* dataMember)
:myVal (offsetof (foo, *dataMember)) //Call this Line (A)


Well, a pointer to member cannot be used without the object.
The expression (*blah) where 'blah' is a pointer to member is
meaningless in C++.

V
Jul 22 '05 #6
On Sat, 08 Jan 2005 12:06:24 -0500, Exits Funnel
<ex***************@yahoo.com> wrote in comp.lang.c++:
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)
{
// int i = offsetof (foo, *dataMember); //Call this Line (B)
}
};
//End test1.cpp

when I try to compile test1.cpp with g++, the compiler has this to say:

test2.cpp: In constructor `bar::bar(int foo::*)':
test2.cpp:6: syntax error before `;' token

A couple of questions then:

(1) Should the compiler complain? I don't have much experience with
using the 'pointer to data member' stuff, but based on the research I've
just done on the net, the code seems reasonable.

(2) If I move the call from the initializer list to the ctor body by
commenting out line (A) and uncommenting line (B), the compiler error
becomes:

test2.cpp: In constructor `bar::bar(int foo::*)':
test2.cpp:8: syntax error before `;' token
test2.cpp:8: declaration of `dataMember' shadows a parameter
test2.cpp:8: syntax error before `;' token

So, it seems the original problem persists which is reasonable but now
there's this additional shadowing issue. It's not clear to me what
parameer 'dataMember' is shadowing here? If anyone could explain this
to me it would be great.

Thanks in advance for any feedback!

-exits


offsetof, defined in <stdlib.h> and <cstdlib>, is a macro, not a
function. It does not work on objects at all, but on compile-time
symbols.

The offsetof() macro requires two arguments, the NAME of a structure
(or in C++, POD class) type, and the NAME of a member of that
structure or class. The macro generates, _at compile time_ a value of
type size_t that represents the difference in bytes between the
address of any valid object of that type, and the address of the
specified member within that object.

It is evaluated completely at compile time based on names, never at
run time and can never involve a pointer. The concept of pointers,
let alone dereferencing pointers, does not exist at the early phase of
compilation where macros are expanded.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 22 '05 #7
On Sat, 08 Jan 2005 16:21:52 -0500 in comp.lang.c++, Exits Funnel
<ex***************@yahoo.com> wrote,
It's not clear to me though what makes foo not a POD. Is it just that
the members are private? I just modified the code to make them public
but I get the same error.
In your stripped example, it is just the private members, but I
guess there may be a lot of other things in the real code.

Plain Old Data is any built in or user-defined type that has:

- no user-defined constructor
- no user-defined copy assignment operator
- no user defined destructor
- no virtual functions
- no base class (i.e. it is not a derived class)
- no private or protected non-static data members
- no non-static members of type pointer to member
- no non-static members that are references
- no non-static data members that are not also POD types

But that has little to do with the current problem.
Good point. Actually, I always try to trim as much of the code away as
possible while still retaining the error before posting to USENET.
Maybe I went a bit too far this time :) The actual code was, of course,
something like this:

bar (int foo::* dataMember)
:myVal (offsetof (foo, *dataMember)) //Call this Line (A)


Different compilers can be expected to implement 'offsetof' in
slightly different ways, to match their differing object model.
Here is an example of a definition of 'offsetof' ripped from a
compiler that I happened to have handy:

#define offsetof(t,i) ((size_t)((char *)&((t *)0)->i - (char *)0))

You notice the second parameter appears in the context '->i'. When
you substitute the macro argument, you get '->*datamember', invoking
the ->* operator almost by accident and luck. If the macro had been
written with '-> i' it would still work with a member name, but not
the pointer.

If foo is a POD your luck may hold. If the *datamember pointer
involves any of the magic that is needed to implement member
pointers when an inheritance hierarchy is involved, etc., then it
becomes less likely that '(t *)0' will slide to success.

Either way, '*datamember' is not what 'offsetof' was designed to
support.

Jul 22 '05 #8
> This is good to know; I couldn't find much info on offsetof anywhere.
It's not clear to me though what makes foo not a POD. Is it just that the members are private? I just modified the code to make them public but I get the same error.


Being private _does_ keep them from being POD (I'm not sure what I was
thinking when I said otherwise) but my original point about the problem
remains -- the real problem is that you're supplying a pointer to a
member but it needs the name of a member instead. The bottom line is
that this technique simply can't work, whether it's applied to a POD
type or not.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 22 '05 #9

David, thanks for taking the time to reply.
#define offsetof(t,i) ((size_t)((char *)&((t *)0)->i - (char *)0))
In which header did you find this? It's not clear to me what the point
of the ' - (char *)0' bit is. The only macro definition I could find on
my platform (RedHat Linux) was in stddef.h and looked like this:

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

Actually, I wasn't #including stddef.h which is obviously part of my
problem. I thought that offsetof( ) was a built in part of the language
similar to sizeof. Would one expect to have to explicitly include some
header file to use offsetof?
You notice the second parameter appears in the context '->i'. When
you substitute the macro argument, you get '->*datamember', invoking
the ->* operator almost by accident and luck. If the macro had been
written with '-> i' it would still work with a member name, but not
the pointer.

If foo is a POD your luck may hold. If the *datamember pointer
involves any of the magic that is needed to implement member
pointers when an inheritance hierarchy is involved, etc., then it
becomes less likely that '(t *)0' will slide to success.

Either way, '*datamember' is not what 'offsetof' was designed to
support.


This is all very helpful information, thanks again.

-exits

Jul 22 '05 #10

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) ...
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...
7
by: Fred Zwarts | last post by:
Consider the following definition: typedef struct { int a; int b; } s; Now I have a function void f (int i) { ... }
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
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.