Reputation: 1824
I'm trying to add a socket filter to one of my sockets in C++ (Linux). In the socket filter I need to get the offset of struct fork_proc_event, which is nested within another structure. The definition looks like this (cn_proc.h):
struct proc_event { ... union { ... struct fork_proc_event { __kernel_pid_t parent_pid; ... } fork; ... } event_data; ... };
In C I would do this:
int off = offsetof(struct fork_proc_event, parent_pid);
However I'm developing in C++. If I try to do this:
int off = offsetof(proc_event::fork_proc_event, parent_pid);
I get the following error:
error: expected type-specifier error: expected `,' error: expected `)' before ',' token
How should the offsetof() line look like?
Upvotes: 2
Views: 3882
Reputation: 320631
I don't exactly understand the need for all those hacks, when all you have to do is give a name to your nested union
type. Any name, just to be able to refer to it in C++ code
struct proc_event {
...
union whatever {
...
struct fork_proc_event {
__kernel_pid_t parent_pid;
...
} fork;
...
} event_data;
...
};
Then you'll be able to refer to it as proc_event::whatever::fork_proc_event
in offsetof
in C++ code
size_t off = offsetof(proc_event::whatever::fork_proc_event, parent_pid);
If you are interested in offset of parent_pid
from the beginning of proc_event
, you can do
size_t off = offsetof(proc_event, event_data.fork.parent_pid);
If you cannot change the declaration, you can calculate the offset of parent_pid
inside fork_proc_event
by doing
size_t off =
offsetof(proc_event, event_data.fork.parent_pid) -
offsetof(proc_event, event_data.fork);
(Although I can't say right away whether the last two are formally legal examples of offsetof
usage, they will normally work in practice without any problems.)
Upvotes: 5
Reputation: 40254
It may help to think of how an implementation of an offsetof
macro might go. Here's one example:
#define offsetof(TYPE, MEMBER) \
((uintptr_t)&(((TYPE*)0)->MEMBER))
In other words, using 0
as a pointer to the type you're interested in, and simply taking the address of the struct field...
So if you wanted the offset of parent_pid
relative to fork
(which is how I initially parsed your question):
((char*)&((struct proc_event*)0)->event_data.fork.parent_pid) - ((char*)&((struct proc_event*)0)->event_data.fork)
On second reading it sounds like you might just want the offset of parent_pid
relative to the start of struct proc_event
. Adapting the example above that would be:
((uintptr_t)&((struct proc_event*)0)->event_data.fork.parent_pid)
Upvotes: 6