Topic: What can new_handler do? Was: can't use STL in commercial applications


Author: andrewb@graphsoft.com (Andrew C. Bell)
Date: 1996/10/17
Raw View
kanze@gabi-soft.fr (J. Kanze) wrote:
>andrewb@graphsoft.com (Andrew C. Bell) writes:
[Lots of stuff back and forth regarding new_handler, and what exactly
one can do -- for example, my proposing creating a dialog
box/requester that requests the user free memory by closing other
apps, or cancel this operation]

>I'm not saying that [the dialog box] is globally too dangerous.  If you want
>to pop up a dialog box, you are not writing portable code.  If your vendor
>documents that this does not require dynamic memory, then why not?

Actually, I'd counter that even if it does require dynamic memory, it
is *still* allowable.  The required behaviour specifies the conditions
that must exist when new_handler() is exited, not what it can do in
the interim.  Now, if your version of new_handler() needs dynamic
allocation, there's the risk that it might fail.  Thus you need to
aware of and take action to avoid infinite loops (as that failure will
also call new_handler()).  But if you do so, as long as you don't
eventually return from your new_handler() without freeing up memory,
or throw an exception out of it not derived from bad_alloc, what
happens inside is not restricted.

After all, what is there to restrict you?

Andrew Bell
andrewb@graphsoft.com abell@mindspring.com




[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/10/10
Raw View
andrewb@graphsoft.com (Andrew C. Bell) writes:

> Speaking genericly: In some cases, if a program is performing a
> modification when a request for more memory cannot be fulfilled, it
> may be impossible to save the current data because it is in an
> inconsistent state.  I would hope that _set_new_handler called a
> routine that told the user (via dialog or whatever) something like the
> following:

To bring this thread back on a standardization topic:-), this is a good
suggestion, but exactly what library functions can legally be called in
a new_handler?  Obviously, any library function which calls operator new
is out.  But the draft standard doesn't state which functions are
guaranteed not to call operator new.  Thus, for example, I would say
that input and output are probably not allowed, because there is no
guarantee that they do not allocate memory dynamically.  (In fact, in
most implementations, they *DO* call operator new.)

--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: andrewb@graphsoft.com (Andrew C. Bell)
Date: 1996/10/14
Raw View
kanze@gabi-soft.fr (J. Kanze) wrote:
>andrewb@graphsoft.com (Andrew C. Bell) writes:
>> [Proposing that on out-of-memory, a dialog requests that the user
>> free memory or cancel the operation]

>To bring this thread back on a standardization topic:-), this is a good
>suggestion, but exactly what library functions can legally be called in
>a new_handler?

At least from the '95 DWP, we have:
18.4.2.2  Type new_handler
Required behaviour:
A new_handler shall perform one of the following:
  --make more storage available for allocation and then return;
  --throw  an  exception  of  type  bad_alloc  or  a  class derived

    from bad_alloc;
  --call either abort() or exit()

And 17.1 Definitions:
[...]
  --required behavior: A description of replacement function and
handler function semantics, applicable to both the behavior provided
by the implementation  and the behavior that shall be provided by any
function definition in the program.  If a function defined in a C++
program  fails  to  meet  the  required  behavior when it executes,
the behavior is undefined.

Now, what the program can do to "make more storage available"
certainly leaves wiggle room.  However, doing anything that might call
operator new gives plenty of opportunity for infinite loops.  Seems to
me that it is the responsibility of the author of the replacement
new_handler() function to make sure his code performs the required
behaviour; certainly, it would require more knowledge of the compiler
than generally is available.  Given this, I would change my proposed
approach (going somewhat off-topic again.) Instead of overloading
new_handler(), which really should be done only with a function that
can make more storage available, I would suggest a "looping" try block
that tries to allocate, catches any out-of-mem failure, and plunks up
my dialog if possible at that point.  You are quite right in pointing
out that doing this inside new_handler() is probably too dangerous.

I do wish, incidentally, that new_handler() had a parameter that
indicated just how much memory the allocation was for.  That way there
wouldn't be the risk of a loop, where new_handler keeps freeing up
blocks that still aren't enough for the new func to allocate a large
enough block.

>Obviously, any library function which calls operator new
>is out.

Not absolutely necessarily.  One's overloaded new handler could set a
flag on entrance and clear it on exit, so that if it is entered while
still trying to handle an initial failure, it would know it is in a
looping state and it could just throw an exception at that point.

It probably would only be practical to pop up a dialog in a
new_handler() replacement if the amount of memory in the failing
allocation is large.  Large allocations are rare enough, however, that
they're generally worth the cost of the looping try block proposed
above.  Since they're typically array allocations -- for example, the
memory for a bitmap -- that code might even be templatable:

template <class Type> Type *
newArray(Type *dummy,long size) // dummy is to identify template type
{
 bool allocated = false;
 while ( !allocated )
 {
  try
  {
   Type *typePtr = new Type[size];
   allocated = true;
   return typePtr;
  }
  catch (/*bad_alloc*/)
  {
   // pop up dialog..
   if ( /* user says cancel action */ )
    throw bad_alloc;
  }
 }
}





[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/10/15
Raw View
andrewb@graphsoft.com (Andrew C. Bell) writes:

> kanze@gabi-soft.fr (J. Kanze) wrote:
> >andrewb@graphsoft.com (Andrew C. Bell) writes:
> >> [Proposing that on out-of-memory, a dialog requests that the user
> >> free memory or cancel the operation]
>
> >To bring this thread back on a standardization topic:-), this is a good
> >suggestion, but exactly what library functions can legally be called in
> >a new_handler?
>
> At least from the '95 DWP, we have:
> 18.4.2.2  Type new_handler
> Required behaviour:
> A new_handler shall perform one of the following:
>   --make more storage available for allocation and then return;
>   --throw  an  exception  of  type  bad_alloc  or  a  class derived
>
>     from bad_alloc;
>   --call either abort() or exit()
>
> And 17.1 Definitions:
> [...]
>   --required behavior: A description of replacement function and
> handler function semantics, applicable to both the behavior provided
> by the implementation  and the behavior that shall be provided by any
> function definition in the program.  If a function defined in a C++
> program  fails  to  meet  the  required  behavior when it executes,
> the behavior is undefined.
>
> Now, what the program can do to "make more storage available"
> certainly leaves wiggle room.  However, doing anything that might call
> operator new gives plenty of opportunity for infinite loops.  Seems to
> me that it is the responsibility of the author of the replacement
> new_handler() function to make sure his code performs the required
> behaviour; certainly, it would require more knowledge of the compiler
> than generally is available.  Given this, I would change my proposed
> approach (going somewhat off-topic again.) Instead of overloading
> new_handler(), which really should be done only with a function that
> can make more storage available, I would suggest a "looping" try block
> that tries to allocate, catches any out-of-mem failure, and plunks up
> my dialog if possible at that point.  You are quite right in pointing
> out that doing this inside new_handler() is probably too dangerous.

I'm not saying that it is globally too dangerous.  If you want to pop up
a dialog box, you are not writing portable code.  If you vendor
documents that this does not require dynamic memory, then why not?

My question concerns portable code.  I want to write something that will
work on all implementations.  In that case, I can, in practice, use only
my own functions, or standard library functions; any others may not be
available on the target platform.  Now, I know (or should know) which of
my own functions require dynamic memory.  The remaining question is the
library functions.

--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]