Multiple Abstract Base Classes, Offset & Weird

Jacob Smith jnsmith@utmb.edu
Wed Sep 10 20:27:00 GMT 2003


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)





More information about the Gcc-help mailing list