[PPL-devel] Re: Feature request: optionally compile with support for exceptions

Roberto Bagnara bagnara at cs.unipr.it
Tue Oct 23 15:54:41 CEST 2001


"Niels Möller" wrote:
> If I understand the issue correctly, the question is whether or not
> 
> extern "C" {
>   static void *
>   cxx_alloc(size_t size) { return new char [size]; }
> 
>   static void *
>   cxx_realloc(void *p, size_t old_size, size_t new_size)
>   { /* Left as an exercise ;-) }
> 
>   static void
>   cxx_free(void *p, size_t size) { delete [] (char *) p ; }
> }
> 
>   ...
> 
>   mp_set_memory_functions(cxx_alloc, cxx_realloc, cxx_free);
> 
> will work when new raises an exception. Right?

Exactly.  Here is the file ac_check_gmp_exceptions.m4 the we use
for autoconfiscating the Parma Polyhedra Library:

dnl Copyright (C) 2001 Roberto Bagnara <bagnara at cs.unipr.it>
dnl  
dnl This file is free software; as a special exception the author gives
dnl unlimited permission to copy and/or distribute it, with or without 
dnl modifications, as long as this notice is preserved.
dnl 
dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
dnl
AC_DEFUN([AC_CHECK_GMP_EXCEPTIONS],
[AC_CACHE_CHECK([whether GMP has been compiled with support for exceptions],
ac_cv_gmp_supports_exceptions,
[AC_LANG_SAVE
 AC_LANG_CPLUSPLUS
 AC_TRY_RUN([
#include <gmp.h>
#include <new>
#include <cstddef>
#include <cstdlib>

using namespace std;

static void*
x_malloc(size_t) {
  throw bad_alloc();
}

static void*
x_realloc(void*, size_t, size_t) {
  throw bad_alloc();
}

static void
x_free(void*, size_t) {
}

int main() {
  mp_set_memory_functions(x_malloc, x_realloc, x_free);
  try {
    mpz_t pie;
    mpz_init_set_str(pie, "3141592653589793238462643383279502884", 10);
  }
  catch (bad_alloc) {
    exit(0);
  }
  exit(1);
}
],
 ac_cv_gmp_supports_exceptions=yes,
 ac_cv_gmp_supports_exceptions=no,
 ac_cv_gmp_supports_exceptions=no)
 AC_LANG_RESTORE
])
gmp_supports_exceptions=${ac_cv_gmp_supports_exceptions}
if test x"$gmp_supports_exceptions" = xyes
then
  value=1
else
  value=0
fi
AC_DEFINE_UNQUOTED(GMP_SUPPORTS_EXCEPTIONS, $value,
  [Not zero if GMP has been compiled with support for exceptions.])
])

> To me it seems a little dangerous even if -fexceptions is used and it
> seems to work. I don't know which gmp functions allocate temporary
> storage outside of the stack, which will leak when a C++ exception is
> raised (most function use TMP_ALLOC, which on most platforms allocates
> storage on the stack).

Hey, wait a minute!
This is not my reading of the GMP documentation.

  Custom Allocation
  *****************

     By default, GMP uses `malloc', `realloc' and `free' for memory
  allocation.  If `malloc' or `realloc' fails, GMP prints a message to
  the standard error output and terminates execution.

     Some applications might want to allocate memory in other ways, or
  might not want a fatal error when there is no more memory available.
  To accomplish this, you can specify alternative memory allocation
  functions.

     This can be done in the Berkeley compatibility library as well as
  the main GMP library.

  ...


Not only I expect all allocations that may fail to be done through the
custom allocation functions;  I also expect GMP not to leave inconsistent
objects around in case of allocation failures.  And it would also be
very desirable that no memory is leaked in that cases (this is harder
to achieve and can be left as a desideratum).

Can someone in the knows comment on all the issues raised here?
All the best,

   Roberto


-- 
Roberto Bagnara
Computer Science Group
Department of Mathematics, University of Parma, Italy
http://www.cs.unipr.it/~bagnara/
mailto:bagnara at cs.unipr.it



More information about the PPL-devel mailing list