Connecting Tech Pros Worldwide Help | Site Map

Trouble with offsetof

  #1  
Old July 23rd, 2005, 12:31 AM
Exits Funnel
Guest
 
Posts: n/a
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

  #2  
Old July 23rd, 2005, 12:31 AM
Victor Bazarov
Guest
 
Posts: n/a

re: Trouble with offsetof


"Exits Funnel" <exitsNOfunnelSPAM@yahoo.com> wrote...[color=blue]
> 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.[/color]

'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


  #3  
Old July 23rd, 2005, 12:31 AM
Jerry Coffin
Guest
 
Posts: n/a

re: Trouble with offsetof


> 'offsetof' is reserved and defined only when used with POD. Your
class[color=blue]
> is not POD, so using 'offsetof' with it is essentially prohibited.[/color]

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.

  #4  
Old July 23rd, 2005, 12:31 AM
Exits Funnel
Guest
 
Posts: n/a

re: Trouble with offsetof


Thanks for taking the time to reply, Victor.
[color=blue]
> 'offsetof' is reserved and defined only when used with POD. Your class
> is not POD, so using 'offsetof' with it is essentially prohibited.[/color]

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.
[color=blue]
>
> 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'.[/color]

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.
[color=blue]
>
> 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?[/color]

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
[color=blue]
>[/color]

  #5  
Old July 23rd, 2005, 12:31 AM
Victor Bazarov
Guest
 
Posts: n/a

re: Trouble with offsetof


"Jerry Coffin" <jcoffin@taeus.com> wrote...[color=blue][color=green]
>> 'offsetof' is reserved and defined only when used with POD. Your[/color]
> class[color=green]
>> is not POD, so using 'offsetof' with it is essentially prohibited.[/color]
>
> 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.[/color]

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

V


  #6  
Old July 23rd, 2005, 12:31 AM
Victor Bazarov
Guest
 
Posts: n/a

re: Trouble with offsetof


"Exits Funnel" <exitsNOfunnelSPAM@yahoo.com> wrote...[color=blue]
> [...] 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)[/color]

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


  #7  
Old July 23rd, 2005, 12:32 AM
Jack Klein
Guest
 
Posts: n/a

re: Trouble with offsetof


On Sat, 08 Jan 2005 12:06:24 -0500, Exits Funnel
<exitsNOfunnelSPAM@yahoo.com> wrote in comp.lang.c++:
[color=blue]
> 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[/color]

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
  #8  
Old July 23rd, 2005, 12:32 AM
David Harmon
Guest
 
Posts: n/a

re: Trouble with offsetof


On Sat, 08 Jan 2005 16:21:52 -0500 in comp.lang.c++, Exits Funnel
<exitsNOfunnelSPAM@yahoo.com> wrote,[color=blue]
>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.[/color]

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.
[color=blue]
>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)[/color]

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.

  #9  
Old July 23rd, 2005, 12:32 AM
Jerry Coffin
Guest
 
Posts: n/a

re: Trouble with offsetof


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

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.

  #10  
Old July 23rd, 2005, 12:32 AM
Exits Funnel
Guest
 
Posts: n/a

re: Trouble with offsetof



David, thanks for taking the time to reply.
[color=blue]
> #define offsetof(t,i) ((size_t)((char *)&((t *)0)->i - (char *)0))[/color]

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?
[color=blue]
> 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.
>[/color]

This is all very helpful information, thanks again.

-exits

Closed Thread


Similar Threads
Thread Thread Starter Forum Replies Last Post
Trouble with malloc(). Pegboy answers 8 November 13th, 2005 11:15 PM
comp.lang.c Answers to Frequently Asked Questions (FAQ List) Steve Summit answers 0 November 13th, 2005 09:56 PM
comp.lang.c Answers to Frequently Asked Questions (FAQ List) Steve Summit answers 0 November 13th, 2005 03:15 AM
Help with boost::python and documentation tools (e.g. pydoc) Neal D. Becker answers 0 July 18th, 2005 05:03 PM