Version 9 of Fixing C Access to Bignums

Updated 2009-09-30 16:56:46 by dgp

The following routines in Tcl's public interface, tcl.h, make use of the mp_int type:

  • Tcl_NewBignumObj(mp_int *)
  • Tcl_DbNewBignumObj(mp_int *, const char *, int)
  • Tcl_SetBignumObj(Tcl_Obj *, mp_int *)
  • Tcl_GetBignumFromObj(Tcl_Interp *, Tcl_Obj *, mp_int *)
  • Tcl_TakeBignumFromObj(Tcl_Interp *, Tcl_Obj *, mp_int *)
  • Tcl_InitBignumFromDouble(Tcl_Interp *, double, mp_int *)

Tcl's public header, tcl.h also includes these declarations:

#ifndef MP_INT_DECLARED
typedef struct mp_int mp_int;
#define MP_INT_DECLARED
#endif
#ifndef MP_DIGIT_DECLARED
typedef unsigned long mp_digit;
#define MP_DIGIT_DECLARED
#endif

which allows the compiler to make sense of the function declarations.

Callers of those functions must be able to allocate an mp_int struct so they can pass its address in. In order to do this a definition of the mp_int struct has to be in scope, but Tcl's public header tcl.h does not provide one.

Q1: What header file are callers of these routines expected to #include to get a suitable mp_int definition in scope?

Q2: If the answer is something other than a corrected tcl.h, how are we to verify that the mp_digit definition active wherever that definition comes from is the same as that in tcl.h? ( Failure to make them consistent leads to a binary incompatibility).

Several of Tcl's own source code files need to call these routines. They have the same problem. Their solution is #include "tommath.h". When Tcl sources are built, the -I compiler options are set so that this refers to the file tcl/generic/tommath.h which is only a wrapper pulling in tcl/generic/tclTomMath.h which is a patched version of the original header of libtommath, tcl/libtommath/tommath.h. That's the Tcl internals answer to Q1.

Each Tcl source file using the mp_int struct, follows the pattern of #include "tcl.h" before #include "tommath.h". Also the file tcl/generic/tclTomMath.h has been patched so that when MP_DIGIT_DECLARED is defined, any declarations of mp_digit are skipped. This combination is the Tcl internals answer to Q2.

more to come...