This is the mail archive of the gcc-help@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]
Other format: [Raw text]

Re: Multiple Abstract Base Classes, Offset & Weird


If GetHashedValue() is a function that allocates an instance of class concrete, and returns a char * (+4?), this is the correct behavior, as the type cast is not safe. The +4 offset accounts for the vtable pointer of 'base_1', aligning a 'concrete' pointer to be a 'base_2'.

Jacob Smith wrote:
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)






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