C++ wrong-code bug: Inheritance & destructors
Brad Aagaard
baagaard@caltech.edu
Tue Nov 7 09:43:00 GMT 2000
Originator: Brad Aagaard
Organization:
Confidential: no
Synopsis: gcc 2.95 calls member function in parent class instead of
member function in derived class
Severity: serious
Priority: medium
Category: c++
Class: wrong-code
Release: gcc version 2.95.2 19991024 (release)
Environment: SunOS 5.6 Generic_105181-17 sun4u sparc SUNW,Ultra-5_10
sparc-sun-solaris2.6/2.95.2/specs
Description: After the destructor is called for an object of a derived
class (DerivedBox), when a derived class member function
(DerivedBox::CallShow) calls another derived class member function
(DerivedBox::Show) that has the same name and type as a parent class
member function (ParentBox::Show), the member function in the parent
class (ParentBox::Show) is called instead of the member function in
the derived class (DerivedBox::Show).
How-to-Repeat:
# 1 "Box3.C"
# 1 "/usr/include/stdio.h" 1 3 4
#pragma ident "@(#)stdio.h 1.49 97/05/09 SMI"
# 1 "/usr/include/sys/feature_tests.h" 1 3 4
#pragma ident "@(#)feature_tests.h 1.13 97/06/26 SMI"
extern "C" {
}
# 17 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/sys/va_list.h" 1 3 4
#pragma ident "@(#)va_list.h 1.6 96/01/26 SMI"
extern "C" {
# 41 "/usr/include/sys/va_list.h" 3 4
typedef void *__va_list;
}
# 18 "/usr/include/stdio.h" 2 3 4
extern "C" {
typedef unsigned int size_t;
typedef long long __longlong_t;
typedef long off_t;
typedef __longlong_t off64_t;
typedef long fpos_t;
typedef __longlong_t fpos64_t;
# 122 "/usr/include/stdio.h" 3 4
typedef struct
{
int _cnt;
unsigned char *_ptr;
unsigned char *_base;
unsigned char _flag;
unsigned char _file;
} FILE;
extern FILE __iob[20 ];
extern FILE *_lastbuf;
extern unsigned char *_bufendtab[];
extern unsigned char _sibuf[], _sobuf[];
# 222 "/usr/include/stdio.h" 3 4
extern int remove(const char *);
extern int rename(const char *, const char *);
extern FILE *tmpfile(void);
extern char *tmpnam(char *);
extern int fclose(FILE *);
extern int fflush(FILE *);
extern FILE *fopen(const char *, const char *);
extern FILE *freopen(const char *, const char *, FILE *);
extern void setbuf(FILE *, char *);
extern void setbuffer(FILE *, char *, size_t);
extern int setlinebuf(FILE *);
extern int setvbuf(FILE *, char *, int, size_t);
extern int fprintf(FILE *, const char *, ...);
extern int fscanf(FILE *, const char *, ...);
extern int printf(const char *, ...);
extern int scanf(const char *, ...);
extern int snprintf(char *, size_t, const char *, ...);
extern int sprintf(char *, const char *, ...);
extern int sscanf(const char *, const char *, ...);
extern int vfprintf(FILE *, const char *, __va_list);
extern int vprintf(const char *, __va_list);
extern int vsnprintf(char *, size_t, const char *, __va_list);
extern int vsprintf(char *, const char *, __va_list);
extern int fgetc(FILE *);
extern char *fgets(char *, int, FILE *);
extern int fputc(int, FILE *);
extern int fputs(const char *, FILE *);
extern int getc(FILE *);
extern int getchar(void);
extern char *gets(char *);
extern int putc(int, FILE *);
extern int putchar(int);
extern int puts(const char *);
extern int ungetc(int, FILE *);
extern size_t fread(void *, size_t, size_t, FILE *);
extern size_t fwrite(const void *, size_t, size_t, FILE *);
extern int fgetpos(FILE *, fpos_t *);
extern int fseek(FILE *, long, int);
extern int fsetpos(FILE *, const fpos_t *);
extern long ftell(FILE *);
extern void rewind(FILE *);
extern void clearerr(FILE *);
extern int feof(FILE *);
extern int ferror(FILE *);
extern void perror(const char *);
extern int __filbuf(FILE *);
extern int __flsbuf(int, FILE *);
extern FILE *fdopen(int, const char *);
extern char *ctermid(char *);
extern int fileno(FILE *);
# 319 "/usr/include/stdio.h" 3 4
extern FILE *popen(const char *, const char *);
extern char *cuserid(char *);
extern char *tempnam(const char *, const char *);
extern int getopt(int, char *const *, const char *);
extern int getsubopt(char **, char *const *, char **);
extern char *optarg;
extern int optind, opterr, optopt;
extern int getw(FILE *);
extern int putw(int, FILE *);
extern int pclose(FILE *);
extern int fseeko(FILE *, off_t, int);
extern off_t ftello(FILE *);
extern FILE *fopen64(const char *, const char *);
extern FILE *freopen64(const char *, const char *, FILE *);
extern FILE *tmpfile64(void);
extern int fgetpos64(FILE *, fpos64_t *);
extern int fsetpos64(FILE *, const fpos64_t *);
extern int fseeko64(FILE *, off64_t, int);
extern off64_t ftello64(FILE *);
# 467 "/usr/include/stdio.h" 3 4
# 515 "/usr/include/stdio.h" 3 4
}
# 1 "Box3.C" 2
class ParentBox
{
public :
ParentBox (void);
virtual ~ParentBox (void);
virtual void Show (void);
};
inline ParentBox::ParentBox (void) {};
inline ParentBox::~ParentBox (void) {};
inline void ParentBox::Show (void) { printf("parent method\n"); };
class DerivedBox : public ParentBox
{
public :
DerivedBox (void);
virtual ~DerivedBox (void);
virtual void Show (void);
void CallShow (void);
};
inline DerivedBox::DerivedBox (void) {};
inline DerivedBox::~DerivedBox (void) {};
inline void DerivedBox::Show (void) { printf("derived method\n"); };
inline void DerivedBox::CallShow (void) { Show(); };
int main (int argc, char* argv[])
{
DerivedBox box;
box.CallShow();
box.DerivedBox::~DerivedBox();
box.CallShow();
return 0;
}
Fix:
1. Do not explicitly call destructors unless absolutely necessary.
2. Explicitly call (derived::) class member functions for derived
classes that have the same name and type as member functions in
the parent class.
More information about the Gcc-bugs
mailing list