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