Article View: gnu.g++.bug
Article #907Re: g++ 2.2.2 runs constructor even if operator new() returns 0
From: Mike Stump
Date: Fri, 04 Sep 1992 21:50
Date: Fri, 04 Sep 1992 21:50
565 lines
6807 bytes
6807 bytes
This behavior is under consideration by the ANSI C++ committee, they
are thinking about defining things such that new should never return
0. It would throw an exception instead. This has long been recognized
by g++ as the proper way to do things, and hence its past and current
behavior.
I am inclided not to consider this a bug, until ANSI C++ decides it is.
For now, I would recommend that you try and code your software in such
a way that it will work or be easy to change, either way ANSI decides.
As a practical matter, you can do something like:
p = (void *) malloc (sz);
if (p == 0)
(*__new_handler) ();
return p;
in your g++ operator new code.
> Message-Id: <1992Jul21.191511.2772@jade.ab.ca>
> From: earl@jade.ab.ca (Earl Locken)
> To: bug-g++@prep.ai.mit.edu
> Date: Tue, 21 Jul 1992 19:15:11 GMT
> Organization: Jade Simulations International, Inc.
> 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
Technical Details
Message-ID:
<9209042150.AA00221@cygnus.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!spool.mu.edu!agate!usenet.ins.cwru.edu!magnus.acs.ohio-state.edu!cis.ohio-state.edu!cygnus.com!mrsShow Full Headers
Complete Article Headers
Newsgroups: gnu.g++.bug Path: arc1-ca.pugleaf.net!sparky!uunet!spool.mu.edu!agate!usenet.ins.cwru.edu!magnus.acs.ohio-state.edu!cis.ohio-state.edu!cygnus.com!mrs From: mrs@cygnus.com (Mike Stump) Subject: Re: g++ 2.2.2 runs constructor even if operator new() returns 0 Message-ID: <9209042150.AA00221@cygnus.com> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Fri, 4 Sep 1992 21:50:54 GMT Approved: bug-g++@prep.ai.mit.edu Lines: 568