This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Multiple Abstract Base Classes, Offset & Weird
- From: Jacob Smith <jnsmith at utmb dot edu>
- Cc: GCC HELP <gcc-help at gcc dot gnu dot org>
- Date: Wed, 10 Sep 2003 15:27:42 -0500
- Subject: Multiple Abstract Base Classes, Offset & Weird
- References: <BB8493B7.A6CD%eljay@adobe.com>
GCC-Help -
I have a question about pointer dereference. Here's a mock-up of the
situation:
class base_1 { /* pure abstract base class*/
public:
virtual do_fun () = 0; // ... function
static base_1& get ( /*hash code*/ ) { return
*(base_1*)GetHashedValue(/*hash code*/); } /* a safe cast */
};
class base_2 { /* pure abstract base class*/
public:
virtual more_fun () = 0; // ... function
static base_2& get ( /*hash code*/ ) { return
*(base_2*)GetHashedValue(/*hash code*/); } /* a safe cast */
};
class concrete : public base_1, public base_2 {
// implements stuff
};
/*
... lots of code here ...
The concrete type is unknown at the user-interface for compile-time,
e.g. there is compile-time code which mangles the type during compilation.
*/
base_1::get(/*hash*/).do_fun(); // runs fine
base_2::get(/*hash*/).do_fun(); // crashes
We can repair the code and make it work by doing the following:
static base_2& get( /* hash code */ ) { return
*(base_2*)(GetHashedValue(/*hash code*/)+4); } /* add 4 */
Is this supposed to be this way? Where in the standard is it? Note that
if you switch the order of the abstract base function, you have to
switch the offsets. Now, one way or another I can control type-order at
the library-user level and do compile-time generation of the correct
offsets, so it's not a problem. Just VERY aggravating. Warnings are set
to -Wall, there are none. There are no errors (it *does* compile).
Thanks in advance,
-j.
Compiler:
- MinGW(C/C++ only) Compiler 3.3.1
- Binutils 2.14.90
- Windows32 API 2.3
- MinGW Runtime Lirbraries 3.0
- GNU Debugger(GDB) 5.21
- GNU Make 3.80.0-3
Make:
#################################################################
##
## This Makefile Exported by MinGW DevStudio 2.0
## Copyright (c) 2002 by Parinya Thipchart
##
#################################################################
ifneq (,$(findstring Release, $(CFG)))
override CFG = Release
else
override CFG = Debug
endif
COMPILER_ROOT = C:\\Program Files\\MinGWStudio\\1.0\\MinGW\\
COMPILER_BIN = $(COMPILER_ROOT)bin\\
PROJECT = win-moa
CC = $(COMPILER_BIN)g++.exe
ifeq ($(CFG),Debug)
OBJ_DIR = Debug
OUTPUT_DIR = Debug
TARGET = win-moa.exe
C_INCLUDE_DIRS =
C_PREPROC =
CFLAGS = --pipe -w -g2 -O0 -frtti -fexceptions
RC_INCLUDE_DIRS =
RC_PREPROC =
RCFLAGS =
LIB_DIRS =
LIBS =
LDFLAGS = --pipe -Wl,--subsystem,windows -mwindows
endif
ifeq ($(CFG),Release)
OBJ_DIR = Release
OUTPUT_DIR = Release
TARGET = win-moa.exe
C_INCLUDE_DIRS =
C_PREPROC =
CFLAGS = --pipe -Wall -g0 -O2 -frtti -fexceptions
RC_INCLUDE_DIRS =
RC_PREPROC =
RCFLAGS =
LIB_DIRS =
LIBS =
LDFLAGS = --pipe -s -Wl,--subsystem,windows -mwindows
endif
SRC_OBJS = \
$(OBJ_DIR)\main.o
define build_target
@if not exist "$(OUTPUT_DIR)" mkdir "$(OUTPUT_DIR)"
@echo Linking...
@$(CC) $(LDFLAGS) $(LIB_DIRS) -o "$(OUTPUT_DIR)\$(TARGET)" $(SRC_OBJS)
$(LIBS)
endef
define compile_source
@if not exist "$(OBJ_DIR)" mkdir "$(OBJ_DIR)"
@echo Compiling $<
@$(CC) $(CFLAGS) $(C_PREPROC) $(C_INCLUDE_DIRS) -c "$<" -o "$@"
endef
.PHONY: print_header
$(TARGET): print_header $(SRC_OBJS)
$(build_target)
.PHONY: clean cleanall
cleanall:
@echo Deleting intermediate files for 'win-moa - $(CFG)'
-@del $(OBJ_DIR)\*.o
-@del "$(OUTPUT_DIR)\$(TARGET)"
clean:
@echo Deleting intermediate files for 'win-moa - $(CFG)'
-@del $(OBJ_DIR)\*.o
print_header:
@echo ----------Configuration: win-moa - $(CFG)----------
$(OBJ_DIR)\main.o: main.cpp \
mcu_messagebox.h \
mcu_type_list.h \
mcu_search.h \
mcu_string_conversion.h \
mcu_common.h
$(compile_source)