🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.g++.bug
Article #194

Re: 2.2.2 on rs6000: new[0]

#194
From: Tom McConnell
Date: Thu, 06 Aug 1992 08:41
128 lines
4692 bytes
  I got to worrying about this problem again, and I decided I don't agree with
what I said (I tend to be a mite schizophrenic :)  I have decided I agree with
Doug Moore that g++ does not exhibit the correct behaviour. My comments about
malloc on AIX are misleading and out of context, and I will try to explain.

  I have (hopefully) provided a better explanation in this message:

In article <9208031516.AA27492@thunder>, tmcconne@sedona.intel.com (Tom McConnell) writes:
> Reply-To: tmcconne@sedona.intel.com
> In article <9208022010.AA07155@cs.rice.edu>, dougm@cs.rice.edu (Doug Moore) writes:
> > Attempting to allocate a zero-sized array on an rs6000 model 550
> > results in a runtime error.  This is aix3.2, with the patched
> > assembler.  g++ 2.2.2 with many patches off the net (although the
> > problem has been around for a while, before 2.2.2 even).
  <stuff deleted>

> > <masc41>:dougm % a.out
> > Virtual memory exceeded in `new'
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > <masc41>:dougm % cat junk.cc
> > main()
> > {
> >   int x = 0;
> >   int* p = new int[x];
> > }


  In g++, when malloc returns a "0", "__new_handler" is called:

        void *
        __builtin_new (sz)
             size_t sz;
        {
          void *p;

          p = malloc (sz);
          if (p == 0)
            (*__new_handler) ();
          return p;
        }

  __new_handler defaults to "default_new_handler", which is just this (without
the comments from libgcc2.c):

        #define MESSAGE "Virtual memory exceeded in `new'\n"

        static void
        default_new_handler ()
        {
          write (2, MESSAGE, sizeof (MESSAGE));
          _exit (-1);
        }

  Ok, the interesting part is the "p == 0" from __builtin_new. Using a test
program, I checked to see what malloc returned on different systems.

  Here is the test program:

        #include <stdio.h>
        #ifndef size_t
        #define size_t long unsigned int
        #endif /* size_t */
        extern void *malloc (size_t);
        main()
        {
            void * p;
            size_t sz = 0;
            p = malloc (sz);
            if (p == 0)
              printf("p is 0\n");
            else
              printf("p is not 0\n");
        }

And here are the results:

    System                       Compiler        Result
    ------                       --------        ------
    AIX 3.1                      xlc-1.1.8.11    p is 0
    AIX 3.1                      gcc-2.2.2       p is 0
    AIX 3.2                      xlc-1.2.0.6     p is 0
    AIX 3.2                      xlC-1.0         p is 0
    Sun SPARC (SunOS 4.1.2)      gcc-2.2.2       p is not 0
    Solbourne (SunOS 4.1.2)      gcc-2.2.2       p is not 0
    NCR (i486 SVR4)              gcc-2.2.2       p is not 0
    NCR (i486 SVR4)              cc (MetaWare)   p is not 0
    VAXstation 3100 (ultrix 3.1) gcc-2.2.2       p is not 0
    VAXstation 3100 (ultrix 4.2) gcc-2.2.2       p is not 0
    Sun 386i (SunOS 4.0.2)       gcc-2.2.2       p is not 0

  -- you get the idea

  The point of this is that the RS/6000 is the only machine (that I have) that
does _not_ return "0" for malloc(0). If I change sz to be non-zero, I always get
"p is not 0" for the result.

  My question is now, "what does it mean to return '0' for malloc(0)?" '0' is
not necessarily the same thing as 'NULL'. My mind is beginning to get a little
fuzzy with the definitions. Maybe I can think of a real answer later, but this
might be a first guess:
  
  One way to fix it (thanks to P. Turlais <turlais@halley.total.fr> for pointing
this out) is to change the code for __builtin_new. Section 12.5 of the ARM
suggests you do something like this:

        void *
        __builtin_new (sz)
             size_t sz;
        {
          void *p;

          while ((p = malloc (sz)) == 0) {
              if (_new_handler)
                  (*__new_handler) ();
          return p;
        }

or, you could rewrite default_new_handler. In any case

    Virtual memory exceeded in `new'

is misleading, at best.

  Sorry for the confusion. Next time I'll spend more time reading

    Cheers,

    Tom McConnell
Technical Details
Message-ID: <9208062241.AA41133@thunder>
Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!sedona.intel.com!tmcconne

Show Full Headers
Complete Article Headers
Newsgroups: gnu.g++.bug
Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!sedona.intel.com!tmcconne
From: tmcconne@sedona.intel.com (Tom McConnell)
Subject: Re: 2.2.2 on rs6000: new[0]
Message-ID: <9208062241.AA41133@thunder>
Sender: gnulists@ai.mit.edu
Reply-To: tmcconne@sedona.intel.com
Organization: GNUs Not Usenet
Distribution: gnu
Date: Thu, 6 Aug 1992 08:41:45 GMT
Approved: bug-g++@prep.ai.mit.edu
Lines: 131