This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
The offset of a parent in a child.
- To: "egcs-bugs at egcs dot cygnus dot com" <egcs-bugs at egcs dot cygnus dot com>
- Subject: The offset of a parent in a child.
- From: Dirk Zoller <1164-32 at onlinehome dot de>
- Date: Thu, 25 Nov 1999 20:40:58 +0100
- Organization: none
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)"