This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

The offset of a parent in a child.



Dear GCC maintainers,

I need to know, where inside a child class the parent is located.
To find this byte offset I use a macro like this:

	#define PARENT_OFFSET(T,P) (unsigned ((P *)((T *)16)) - 16)

(Dear compiler, imagine at 16 there is a Child T, give me the address
of the parent P of that child, take that as an unsigned and subtract
the 16). If I used 0 then the special treatment of NULL-pointers would
break the procedure.

This works with the compilers I use (gcc-2.95.2, MS-Visual-C, SunPRO CC).
It does not work any more with 

	test.cc:19: non-lvalue in unary `&'

I don't see another way to find out this information. I tried to rewrite
the macro using C++-style casts, made variations with casts to references,
but nothing helped.


Another issue is, that such an expression is no more a
const expression for gcc. (It was in gcc-2.8.1 and early egcs'es.)

This forces an initialized struct which holds such offsets into the
writable data segment and trivial initialization code being generated.


FYI: In my application I generate records describing my data in order
to allow very generic programming. The described data is organized
hierarchically using C++ inheritance. The descriptor records are written
as initialized structs. This PARENT_OFFSET() macro call is among the
member initializers. There are plenty of these descriptors. It would
be nice if the expression was a "constant expression" again.

With kind regards

Dirk Zoller

-- 
Dirk Zoller					Phone:  +49-69-24004649
Sol-3 GmbH&Co KG				Fax:    +49-69-24004650
Obere Marktstraße 5				e-mail: duz@sol-3.de
63110 Rodgau
Germany

#define PARENT_OFFSET(T,P) (unsigned ((P *)((T *)16)) - 16)

struct x { int n; };
struct y { int m; };

struct z : public x, public y { int k; };

struct h { unsigned x; };

// These work:

const int o1 = PARENT_OFFSET (z, x);
const int o2 = PARENT_OFFSET (z, y);

// But not these:

const h h1 = { PARENT_OFFSET (z, x) };
const h h2 = { PARENT_OFFSET (z, y) };
# 1 "parent-offset.cc"



struct x { int n; };
struct y { int m; };

struct z : public x, public y { int k; };

struct h { unsigned x; };

 

const int o1 = (unsigned ((  x  *)(( z  *)16)) - 16) ;
const int o2 = (unsigned ((  y  *)(( z  *)16)) - 16) ;

 

const h h1 = { (unsigned ((  x  *)(( z  *)16)) - 16)  };
const h h2 = { (unsigned ((  y  *)(( z  *)16)) - 16)  };
cd /home/duz/
c++ -save-temps -v -O -fno-rtti -fno-exceptions -S parent-offset.cc
Reading specs from /opt/gnu/egcs-19991122/lib/gcc-lib/i586-pc-linux-gnu/2.96/specs
gcc version 2.96 19991122 (experimental)
 /opt/gnu/egcs-19991122/lib/gcc-lib/i586-pc-linux-gnu/2.96/cpp -lang-c++ -v -iprefix /opt/gnu/bin/../lib/gcc-lib/i586-pc-linux-gnu/2.96/ -D__GNUC__=2 -D__GNUG__=2 -D__GNUC_MINOR__=96 -D__cplusplus -D__ELF__ -Dunix -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__OPTIMIZE__ -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -D__tune_pentium__ parent-offset.cc parent-offset.ii
GNU CPP version 2.96 19991122 (experimental) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
 /opt/gnu/egcs-19991122/lib/gcc-lib/i586-pc-linux-gnu/2.96/../../../../include/g++-3
 /usr/local/include
 /opt/gnu/egcs-19991122/lib/gcc-lib/i586-pc-linux-gnu/2.96/../../../../i586-pc-linux-gnu/include
 /opt/gnu/egcs-19991122/lib/gcc-lib/i586-pc-linux-gnu/2.96/include
 /usr/include
End of search list.
The following default directories have been omitted from the search path:
End of omitted list.
 /opt/gnu/egcs-19991122/lib/gcc-lib/i586-pc-linux-gnu/2.96/cc1plus parent-offset.ii -quiet -dumpbase parent-offset.cc -O -version -fno-rtti -fno-exceptions -o parent-offset.s
GNU C++ version 2.96 19991122 (experimental) (i586-pc-linux-gnu) compiled by GNU C version 2.96 19991122 (experimental).
parent-offset.cc: In function `void __static_initialization_and_destruction_0 (int, int)':
parent-offset.cc:19: non-lvalue in unary `&'

Compilation exited abnormally with code 1 at Thu Nov 25 20:35:44
	.file	"parent-offset.cc"
	.version	"01.01"
gcc2_compiled.:
	.local	o2
	.comm	o2,4,4
	.local	h2
	.comm	h2,4,4
.text
	.align 16
	.type	 __static_initialization_and_destruction_0,@function
__static_initialization_and_destruction_0:
	pushl	%ebp
	movl	%esp, %ebp
	movl	12(%ebp), %eax
	cmpl	$65535, %eax
	jne	.L3
	cmpl	$1, 8(%ebp)
	jne	.L3
	movl	$4, o2
.L3:
	movl	%ebp, %esp
	popl	%ebp
	ret
.Lfe1:
	.size	 __static_initialization_and_destruction_0,.Lfe1-__static_initialization_and_destruction_0
	.align 16
	.type	 _GLOBAL_.I.parent_offset.ccOitKje,@function
_GLOBAL_.I.parent_offset.ccOitKje:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	subl	$8, %esp
	pushl	$65535
	pushl	$1
	call	__static_initialization_and_destruction_0
	movl	%ebp, %esp
	popl	%ebp
	ret
.Lfe2:
	.size	 _GLOBAL_.I.parent_offset.ccOitKje,.Lfe2-_GLOBAL_.I.parent_offset.ccOitKje
	.section	.ctors,"aw"
	.long	 _GLOBAL_.I.parent_offset.ccOitKje
	.ident	"GCC: (GNU) 2.96 19991122 (experimental)"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]