By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,345 Members | 1,706 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,345 IT Pros & Developers. It's quick & easy.

finding offset of a class member at compile time

P: n/a
Hi,

Is there a way to find the offset of a class member at compile time.
e.g. class A{ int i; int j; char c; };

Here the offset of c = 8 bytes from the start of an object of A
(assuming 4 byte int). Can it be done at compile time.

Thanks in advance

Nov 14 '06 #1
Share this Question
Share on Google+
19 Replies


P: n/a
Geo

Rahul wrote:
Hi,

Is there a way to find the offset of a class member at compile time.
e.g. class A{ int i; int j; char c; };

Here the offset of c = 8 bytes from the start of an object of A
(assuming 4 byte int). Can it be done at compile time.

Thanks in advance
Have you tried offsetof() ?

Nov 14 '06 #2

P: n/a


On Nov 14, 6:31 pm, "Geo" <g...@remm.orgwrote:
Rahul wrote:
Hi,
Is there a way to find the offset of a class member at compile time.
e.g. class A{ int i; int j; char c; };
Here the offset of c = 8 bytes from the start of an object of A
(assuming 4 byte int). Can it be done at compile time.
Thanks in advanceHave you tried offsetof() ?

offset of will do ((A*)0)->i which will happen at run time (not
compile time). But i want to know it at compile time only.

something like &A::i would have been better, but that also dosn't seem
to rum at compile time.

Nov 14 '06 #3

P: n/a

Rahul skrev:
On Nov 14, 6:31 pm, "Geo" <g...@remm.orgwrote:
Rahul wrote:
Hi,
Is there a way to find the offset of a class member at compile time.
e.g. class A{ int i; int j; char c; };
Here the offset of c = 8 bytes from the start of an object of A
(assuming 4 byte int). Can it be done at compile time.
Thanks in advanceHave you tried offsetof() ?


offset of will do ((A*)0)->i which will happen at run time (not
compile time). But i want to know it at compile time only.
How offsetof does its stuff is an implementation detail, but it will
always be a compile-time result. Your problem is another as offsetof is
defined for POD types only. But why do you want to know such stuff in
the first place? Answering that question might give way to the "real"
solution.

/Peter
>
something like &A::i would have been better, but that also dosn't seem
to rum at compile time.
Nov 14 '06 #4

P: n/a
offset of is not giving the result at compile time.

The class is a POD, which has lots of members, the problem is that the
members have to be in a order (at least some of them, well its very
cryptic, but thats how the code has been written)

So to ensure that if somebody changes the class, he dosn't mess up the
order.
I m using a compile time macro, which creates an array of size (offset
(last_member-first_member)) to ensure that last_member is indeed
defined in the last.

Nov 14 '06 #5

P: n/a

Rahul wrote:
offset of is not giving the result at compile time.

The class is a POD, which has lots of members, the problem is that the
members have to be in a order (at least some of them, well its very
cryptic, but thats how the code has been written)

So to ensure that if somebody changes the class, he dosn't mess up the
order.
I m using a compile time macro, which creates an array of size (offset
(last_member-first_member)) to ensure that last_member is indeed
defined in the last.
Probably not the best solution But I think something like the may work

struct {
struct {
struct {
int a;
}A;
int b;
}B;
double c
}C:
char d;
};

Nov 14 '06 #6

P: n/a

Rahul wrote:
offset of is not giving the result at compile time.

The class is a POD, which has lots of members, the problem is that the
members have to be in a order (at least some of them, well its very
cryptic, but thats how the code has been written)

So to ensure that if somebody changes the class, he dosn't mess up the
order.
I m using a compile time macro, which creates an array of size (offset
(last_member-first_member)) to ensure that last_member is indeed
defined in the last.
Probably not the best solution But I think something like the may work

struct {
struct {
struct {
int a;
}A;
int b;
}B;
double c
}C:
char d;
}D;

Nov 14 '06 #7

P: n/a

Rahul wrote:
offset of is not giving the result at compile time.

The class is a POD, which has lots of members, the problem is that the
members have to be in a order (at least some of them, well its very
cryptic, but thats how the code has been written)

So to ensure that if somebody changes the class, he dosn't mess up the
order.
I m using a compile time macro, which creates an array of size (offset
(last_member-first_member)) to ensure that last_member is indeed
defined in the last.
Probably not the best solution But I think something like the may work

struct {
struct {
struct {
int a;
}A;
int b;
}B;
double c
}C:
char d;
}D;

Nov 14 '06 #8

P: n/a
I have NO idea why that apeared 3 times !!

Nov 14 '06 #9

P: n/a

Rahul skrev:
offset of is not giving the result at compile time.
In that case your C++ compiler is nonconforming. To be nonconforming in
this area is somewhat surprising, so I do believe you are wrong here.

NB. an expression such as size_t(&((A*)0)->i)) is a compile time
expression.

/Peter
[snip]

Nov 14 '06 #10

P: n/a
I am using gcc version 3.4.5.
I don;t know if it confirms to the standard or not.

But ((A*)0)-either using offsetof or explicitly is happening at run
time only, otherwise my COMPILE_TIME_ASSERT would have failed because
of -ve size array definition.

But at run time its printing the difference correctly (when i am doing
(first_member-last_member) and vice versa also.

Nov 14 '06 #11

P: n/a
* Rahul:
I am using gcc version 3.4.5.
I don;t know if it confirms to the standard or not.

But ((A*)0)-either using offsetof or explicitly is happening at run
time only, otherwise my COMPILE_TIME_ASSERT would have failed because
of -ve size array definition.

But at run time its printing the difference correctly (when i am doing
(first_member-last_member) and vice versa also.
The bugs are in your code.

Read the FAQ on how to post a question about code that doesn't work
correctly.

Then do as the FAQ says.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '06 #12

P: n/a

Rahul wrote:
Hi,

Is there a way to find the offset of a class member at compile time.
e.g. class A{ int i; int j; char c; };

Here the offset of c = 8 bytes from the start of an object of A
(assuming 4 byte int). Can it be done at compile time.

Thanks in advance
How about this, it works for me. I employ typelists, you just need to
put a typelist in your class, its not ver intrusive because the typedef
is a compile time object.

#include<iostream>
#include<cmath>
using namespace std;

struct null_type{};

template<class TYPE1,class TYPE2>
struct TypeList{
typedef TYPE1 Head;
typedef TYPE2 Tail;
};
template<class TYPE,unsigned long i>
struct At {
typedef typename At<typename TYPE::Tail,i-1>::type type;

};

template<class TYPE>
struct At<TYPE,0{
typedef typename TYPE::Head type;

};
template <class TLIST ,unsigned long i>
struct GetSize{
enum {value = sizeof(typename At<TLIST,i>::type) +
GetSize<TLIST,i-1>::value};
};

template <class TLIST>
struct GetSize<TLIST,0{
enum {value = sizeof(typename At<TLIST,0>::type)};
};

#define TYPELIST_1(type) TypeList<type,null_type>
#define TYPELIST_2(type1,type2) TypeList<type1,TYPELIST_1(type2) >
#define TYPELIST_3(type1,type2,type3)
TypeList<type1,TYPELIST_2(type2,type3) >
#define TYPELIST_4(type1,type2,type3,type4)
TypeList<type1,TYPELIST_3(type2,type3,type4) >

struct A {
typedef TYPELIST_4(int,double,char,unsigned long) theTypeList;
int i;
double x;
char ch;
unsigned long ul;
};
int main() {

cout << GetSize<A::theTypeList,2>::value;

}

Nov 14 '06 #13

P: n/a
Rahul:
Hi,

Is there a way to find the offset of a class member at compile time.
e.g. class A{ int i; int j; char c; };

Here the offset of c = 8 bytes from the start of an object of A
(assuming 4 byte int). Can it be done at compile time.

Thanks in advance

If you're working with a POD, then simply use the "offsetof" macro. If it
doesn't yield a compile-time constant, then you have a K++ compiler.

If working with a non-POD, then I think the only portable method would be to
create an object of it, e.g.:

SomeType obj;

size_t i = (char*)&obj.c - (char*)&obj;

, but this won't give you a compile-time constant.

--

Frederick Gotham
Nov 14 '06 #14

P: n/a

"Rahul" <ra*********@lucent.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.com...
>I am using gcc version 3.4.5.
I don;t know if it confirms to the standard or not.

But ((A*)0)-either using offsetof or explicitly is happening at run
time only, otherwise my COMPILE_TIME_ASSERT would have failed because
of -ve size array definition.
Sounds like your COMPILE_TIME_ASSERT isn't written correctly. But you
haven't shown that code, so that's just a guess. (And I have _no_ idea what
the heck you mean by "-ve size array definition"!)
But at run time its printing the difference correctly (when i am doing
(first_member-last_member) and vice versa also.
Show the code!

-Howard

Nov 14 '06 #15

P: n/a
Its this,

#define COMPILE_TIME_ASSERT(expr) do \
{ \
int temp[(expr) != 0 ? 1 : -1]; \
(void)(temp);\
} while(0)

So the following will casuse a compile time error.
COMPILE_TIME_ASSERT(2-2);

Nov 15 '06 #16

P: n/a
Le 15.11.2006 05:36, :
Its this,

#define COMPILE_TIME_ASSERT(expr) do \
{ \
int temp[(expr) != 0 ? 1 : -1]; \
(void)(temp);\
} while(0)

So the following will casuse a compile time error.
COMPILE_TIME_ASSERT(2-2);
Try this one:

#define CAT__(A,B) A ## B
#define CAT_(A,B) CAT__(A,B)
#define COMPILE_TIME_ASSERT(expr) \
typedef int CAT_(CTA_DummyType,__LINE__)[(expr) ? 1 : -1]

Note that the first CAT__ has two underscores and the second only one.

--
___________
_/ _ \_`_`_`_) Serge PACCALIN -- sp ad mailclub.net
\ \_L_) Pour bien répondre avec Google, ne pas cliquer
-'(__) « Répondre », mais « Afficher les options »,
_/___(_) puis cliquer « Répondre » (parmi les options).
Nov 15 '06 #17

P: n/a
Serge Paccalin wrote:
Le 15.11.2006 05:36, :
>Its this,

#define COMPILE_TIME_ASSERT(expr) do \
{ \
int temp[(expr) != 0 ? 1 : -1]; \
(void)(temp);\
} while(0)

So the following will casuse a compile time error.
COMPILE_TIME_ASSERT(2-2);

Try this one:

#define CAT__(A,B) A ## B
#define CAT_(A,B) CAT__(A,B)
#define COMPILE_TIME_ASSERT(expr) \
typedef int CAT_(CTA_DummyType,__LINE__)[(expr) ? 1 : -1]

Note that the first CAT__ has two underscores and the second only one.
That's unkosher. Any identifier with two consecutive underscores is
reserved to the implementation. Use CAT1_ instead.
Nov 15 '06 #18

P: n/a

"Rahul" <ra*********@lucent.comwrote in message
news:11**********************@m7g2000cwm.googlegro ups.com...
Its this,

#define COMPILE_TIME_ASSERT(expr) do \
{ \
int temp[(expr) != 0 ? 1 : -1]; \
(void)(temp);\
} while(0)

So the following will casuse a compile time error.
COMPILE_TIME_ASSERT(2-2);
(It would help if you'd follow the newsgroup guidelines, and quote what
you're responding to.)

How are you using this macro? You haven't shown the code using this, or the
structure you're using it on. You should always post _complete_ information
here, or else we're left groping in the dark.

Why are you using this declaration?:
int temp[(expr) != 0 ? 1 : -1];

Your code appears to check for inequality, as if all you want is for the two
numbers to be different. I thought you wanted to be sure the _order_ of the
members was correct. How are you doing that? What good does it do to only
accept _unequal_ values? (Hint: show the code!)

Anyway...

I did the following test, and it correctly tells me whether two members are
in the expected order or not:

struct TS1
{
// ok, correct order (a before b)
int a;
char b;
};

struct TS2
{
// not ok, wrong order (a after b)
char b;
int a;
};

#define COMPILE_TIME_ASSERT2(expr) do \
{ \
int temp[(expr)]; \
(void)(temp);\
} while(0)

int main()
{
COMPILE_TIME_ASSERT2(offsetof(TS1,b)-offsetof(TS1,a)); // ok
COMPILE_TIME_ASSERT2(offsetof(TS2,b)-offsetof(TS2,a)); // not ok

// ...
}

That code accepts TS1 fine, but for TS2 it reports that I can't have an
array larger than ffffffff bytes. So there's apparently a signed/unsigned
issue here. If I change the array definition like this:

int temp[(long)(expr)]; \

then I get the expected "negative subscript" error for TS2.

So, I think I've shown that offsetof is (at least with my compiler) a
compile-time value, eh? Try my code on your compiler. If it still fails
(by not causing an error), then you've got a non-compliant compiler.

-Howard

Nov 15 '06 #19

P: n/a
Le 15.11.2006 16:44, :
>#define CAT__(A,B) A ## B
That's unkosher. Any identifier with two consecutive underscores is
reserved to the implementation. Use CAT1_ instead.
OK, I didn't know that. I thought that only identifiers starting with
underscores (like __CAT or _EMAIL) were a problem.

--
___________
_/ _ \_`_`_`_) Serge PACCALIN -- sp ad mailclub.net
\ \_L_) Pour bien répondre avec Google, ne pas cliquer
-'(__) « Répondre », mais « Afficher les options »,
_/___(_) puis cliquer « Répondre » (parmi les options).
Nov 15 '06 #20

This discussion thread is closed

Replies have been disabled for this discussion.