From: earl@jade.ab.CA (Earl Locken)
Subject: g++ 2.2.2 runs constructor even if operator new() returns 0
Organization: Jade Simulations International, Inc.
Distribution: gnu
Date: Tue, 21 Jul 1992 19:15:11 GMT

    g++ executes the constructor if the operator new defined for the
class returns 0.  The ARM, page 61, says:

	... initialization is done only if the value returned by
	the operator new() is nonzero.  If the value returned by 
	the operator new() is 0 (the null pointer) the value of
	the expression is 0.

     Sun CC (and, I would assume, all cfront-based compilers) does not
call the constructor.  This seems to be much preferable to having to
have each constructor check for a NULL this.

     Here's a little test program that shows that g++ runs the
constructor if new() returns 0.

#include <stdio.h>
#include <stddef.h>

class atype {
 public:
	atype();
	void *operator new(size_t size) { return 0; };
	void *operator new(size_t size, int alloc_size) { return 0; };
	void operator delete(void *block) { };
	};

atype::atype()
{
	if (this == 0)
		printf("atype:atype() constructor run illegally\n");
}

main()
{
	atype *x = new atype;
	if (x) delete x;
}

     Here is the cpp-processed version.

g++ -E null-new.C
# 1 "null-new.C"
 
 
 
 
 
 
 
 

# 1 "/usr/local/lib/g++-include/stdio.h" 1 3
 
 
















 


























#pragma interface







 
 
 









# 82 "/usr/local/lib/g++-include/stdio.h" 3


extern "C" {





























# 1 "/usr/local/lib/gcc-lib/sun3-sunos4.1.1/2.2.2a/include/stdio.h" 1 3
 




extern	struct	_iobuf {
	int	_cnt;
	unsigned char *_ptr;
	unsigned char *_base;
	int	_bufsiz;
	short	_flag;
	char	_file;		 
} _iob[];








































extern struct _iobuf 	*__hide_fopen ();
extern struct _iobuf 	*__hide_fdopen ();
extern struct _iobuf 	*__hide_freopen ();
extern struct _iobuf 	*__hide_popen ();
extern struct _iobuf 	*tmpfile();
extern long	ftell();
extern char	*fgets();
extern char	*gets();
extern char	*__hide_sprintf ();
extern char	*ctermid();
extern char	*cuserid();
extern char	*__hide_tempnam ();
extern char	*tmpnam();






# 114 "/usr/local/lib/g++-include/stdio.h" 2 3































}





extern "C" {







int    _doprnt(const char*, void*, struct _iobuf *);
int    _doscan(struct _iobuf *, const char*, ...);
int    _filbuf(struct _iobuf *);
int    _flsbuf(unsigned, struct _iobuf *);


int    fclose(struct _iobuf *);
struct _iobuf *  fdopen(int, const char*);
int    fflush(struct _iobuf *);
int    fgetc(struct _iobuf *);
char*  fgets(char*, int, struct _iobuf  *);
struct _iobuf *  fopen(const char*, const char*);
int    fprintf(struct _iobuf *, const char* ...);
int    fputc(int, struct _iobuf *);
int    fputs(const char*, struct _iobuf *);
int fread(void*, int, int, struct _iobuf *);



struct _iobuf *  freopen(const char*, const char*, struct _iobuf *);

int    fscanf(struct _iobuf *, const char* ...);
int    fseek(struct _iobuf *, long, int);
long   ftell(struct _iobuf  *);
int fwrite(const void*, int, int, struct _iobuf *);
char*  gets(char*);
int    getw(struct _iobuf *);
int    pclose(struct _iobuf *);
void   perror(const char*);
struct _iobuf *  popen(const char*, const char*);
int    printf(const char* ...);
int    puts(const char*);
int    putw(int, struct _iobuf *);
int    rewind(struct _iobuf *);
int    scanf(const char* ...);
int    setbuf(struct _iobuf *, char*);
int    setbuffer(struct _iobuf *, char*, int);
int    setlinebuf(struct _iobuf *);
int    setvbuf(struct _iobuf *, char*, int, int);
int    sscanf(char*, const char* ...);
struct _iobuf *  tmpfile();
int    ungetc(int, struct _iobuf *);
int    vfprintf(struct _iobuf *, const char*, ...);

 
 

int    vprintf(const char*, ... );





char*  sprintf(char*, const char*, ...);
char*  vsprintf(char*, const char*, ...);


}


















# 10 "null-new.C" 2

# 1 "/usr/local/lib/g++-include/stddef.h" 1 3


extern "C" {



# 1 "/usr/local/lib/gcc-lib/sun3-sunos4.1.1/2.2.2a/include/stddef.h" 1 3



 









 


 





 


















 


typedef int ptrdiff_t;









 


 




















 


typedef int size_t;












 





















 


typedef short unsigned int wchar_t;












 









 






# 7 "/usr/local/lib/g++-include/stddef.h" 2 3




}

# 11 "null-new.C" 2


class atype {
 public:
	atype();
	void *operator new(size_t size) { return 0; };
	void *operator new(size_t size, int alloc_size) { return 0; };
	void operator delete(void *block) { };
	};

atype::atype()
{
	if (this == 0)
		printf("atype:atype() constructor run illegally\n");
}

main()
{
	atype *x = new atype;
	if (x == 0) printf("x was 0");
	if (x) delete x;
}


-- 
Earl Locken						earl@jade.ab.ca
Jade Simulations International

Newsgroups: gnu.g++.bug