Problem (with fix) concerning GMP's C++ random number class

Roberto Bagnara bagnara@cs.unipr.it
Tue, 05 Nov 2002 15:18:46 +0100


If you take the following code, that comes straight
from the manual of GMP 4.1, and try to compile it with
a strictly conforming C++ compiler, you will see that
it does not compile.

---------------------------------------------
#include <gmpxx.h>

void foo() {
   gmp_randclass rg(gmp_randinit_default);
}
---------------------------------------------

The reason is that, while the constructors for `gmp_randclass'
have all been declared to take a C++ function pointer, the
invocation above passes a C function pointer.  This is not allowed
by the C++ standard.  One possibility to rectify things is the patch
below, which changes the declarations of the constructors.
Of course, the dual change is also possible, the point being
that C linkage and C++ linkage are incompatible.
All the best

      Roberto

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


*** /usr/local/distrib/gmp-4.1/gmpxx.h	2002-05-08 01:09:50.000000000 +0200
--- gmpxx.h	2002-11-05 15:03:05.000000000 +0100
***************
*** 4968,4973 ****
--- 4968,4981 ----
     }
   };

+ extern "C" typedef void GMP_RANDINIT_DEFAULT(gmp_randstate_t);
+ extern "C" typedef void GMP_RANDINIT_LC_2EXP(gmp_randstate_t,
+ 					     mpz_srcptr,
+ 					     unsigned long int,
+ 					     unsigned long int);
+ extern "C" typedef void GMP_RANDINIT_LC_2EXP_SIZE(gmp_randstate_t,
+ 						  unsigned long int);
+
   class gmp_randclass
   {
   private:
***************
*** 4988,5004 ****
     }

     // gmp_randinit_default
!   gmp_randclass(void (*f)(gmp_randstate_t))
     { f(state); }

     // gmp_randinit_lc_2exp
!   gmp_randclass(void (*f)(gmp_randstate_t, mpz_srcptr,
! 			  unsigned long int, unsigned long int),
   		mpz_class z, unsigned long int l1, unsigned long int l2)
     { f(state, z.get_mpz_t(), l1, l2); }

     // gmp_randinit_lc_2exp_size
!   gmp_randclass(int (*f)(gmp_randstate_t, unsigned long int),
   		unsigned long int size)
     { f(state, size); }

--- 4996,5011 ----
     }

     // gmp_randinit_default
!   gmp_randclass(GMP_RANDINIT_DEFAULT* f)
     { f(state); }

     // gmp_randinit_lc_2exp
!   gmp_randclass(GMP_RANDINIT_LC_2EXP* f,
   		mpz_class z, unsigned long int l1, unsigned long int l2)
     { f(state, z.get_mpz_t(), l1, l2); }

     // gmp_randinit_lc_2exp_size
!   gmp_randclass(GMP_RANDINIT_LC_2EXP_SIZE* f,
   		unsigned long int size)
     { f(state, size); }