Reputation:
I'm wrapping a scripting library and this macro exists.
#define asOFFSET(s,m) ((size_t)(&reinterpret_cast<s*>(100000)->m)-100000)
what type is m
? It has the example:
struct MyStruct
{
int a;
};
asOFFSET(MyStruct,a)
I want to put this into a function.
Upvotes: 0
Views: 83
Reputation: 2138
The macro is (most likely) used by the scripting library to find out the internal layout of a class's members without making assumptions about its type, architecture or inheritance model. (A simple example is discussed here).
For most C++ programs, this information (memory layout) should ideally not be needed at all. But in the off chance that you do need it (e.g. if you're writing an analyser / debugger), you would be better off retaining this macro as-is (or preferably replacing its usage in your code with offsetof
as Michael Anderson points out.) There are compiler-specific implementations which are
With these equivalent options, a hand-spun alternative or wrapper should ideally not be needed.
Upvotes: 1
Reputation: 61498
The purpose of the macro is to determine, given any name of a struct and any name of a member of that struct, the distance in memory from the beginning of an arbitrary instance of the struct, and the location of that member in the same instance.
m
does not have a "type", and neither does s
. The entire concept of "type" goes out the window when you use macros. This stuff simply is not C++; it's basically a completely separate language that's used to edit C++ code in-place. When the preprocessor runs, asOFFSET(MyStruct, a)
will be literally replaced with the text ((size_t)(&reinterpret_cast<MyStruct*>(100000)->a)-100000)
before the compiler even begins its work.
((size_t)(&reinterpret_cast<MyStruct*>(100000)->a)-100000)
is intended to evaluate to 0, because the a
member of MyStruct
instances appears at the beginning of each instance. I'm not actually 100% sure that this is legal behaviour per the specification, but the intent is as follows:
Pretend that there is an instance of MyStruct
at the memory location 100000
, by treating the number 100000
as if it were a pointer to a MyStruct
.
Get the address in memory of the a
member of this fake struct, and subtract 100000
again. That gives us the distance from the beginning of the fake struct to the specified member of that fake struct.
Cast that numeric value back to size_t
(the numeric type used for measuring memory allocations, an unsigned integer type).
Upvotes: 0
Reputation: 73480
This is an implementation of the offsetof
macro. m
is any member of s
. It doesn't have a corresponding C or C++ type - but is closely related to the concept of pointer to member.
Upvotes: 1