## 3 GMP Basics ¶

Using functions, macros, data types, etc. not documented in this manual is strongly discouraged. If you do so your application is guaranteed to be incompatible with future versions of GMP.

### 3.1 Headers and Libraries ¶

All declarations needed to use GMP are collected in the include file `gmp.h`, except for the C++ Class Interface which comes with its own separate header `gmpxx.h`. `gmp.h` is designed to work with both C and C++ compilers.

    #include <gmp.h>

Note however that prototypes for GMP functions with `FILE *` parameters are only provided if `<stdio.h>` is included before.

    #include <stdio.h>
    #include <gmp.h>

Likewise `<stdarg.h>` is required for prototypes with `va_list` parameters, such as `gmp_vprintf`. And `<obstack.h>` for prototypes with `struct obstack` parameters, such as `gmp_obstack_printf`, when available.

All programs using GMP must link against the `libgmp` library. On a typical Unix-like system this can be done with ‘`-lgmp`’, for example

    gcc myprogram.c -lgmp

GMP C++ functions are in a separate `libgmpxx` library, including the C++ Class Interface but also C++ Formatted Output for regular GMP types. This is built and installed if C++ support has been enabled (see Build Options). For example,

    g++ mycxxprog.cc -lgmpxx -lgmp

GMP is built using Libtool and an application can use that to link if desired, see GNU Libtool in GNU Libtool.

If GMP has been installed to a non-standard location then it may be necessary to use ‘`-I`’ and ‘`-L`’ compiler options to point to the right directories, and some sort of run-time path for a shared library.

### 3.2 Nomenclature and Types ¶

In this manual, integer usually means a multiple precision integer, as defined by the GMP library. The C data type for such integers is `mpz_t`. Here are some examples of how to declare such integers:

    mpz_t sum;
    struct foo { mpz_t x, y; };
    mpz_t vec[20];

Rational number means a multiple precision fraction. The C data type for these fractions is `mpq_t`. For example:

    mpq_t quotient;

Floating point number or Float for short, is an arbitrary precision mantissa with a limited precision exponent. The C data type for such objects is `mpf_t`. For example:

    mpf_t fp;

The floating point functions accept and return exponents in the C type `mp_exp_t`. Currently this is usually a `long`, but on some systems it’s an `int` for efficiency.

A limb means the part of a multi-precision number that fits in a single machine word. (We chose this word because a limb of the human body is analogous to a digit, only larger, and containing several digits.) Normally a limb is 32 or 64 bits. The C data type for a limb is `mp_limb_t`.

Counts of limbs of a multi-precision number represented in the C type `mp_size_t`. Currently this is normally a `long`, but on some systems it’s an `int` for efficiency, and on some systems it will be `long long` in the future.

Counts of bits of a multi-precision number are represented in the C type `mp_bitcnt_t`. Currently this is always an `unsigned long`, but on some systems it will be an `unsigned long long` in the future.

Random state means an algorithm selection and current state data. The C data type for such objects is `gmp_randstate_t`. For example:

    gmp_randstate_t rstate;

Also, in general `mp_bitcnt_t` is used for bit counts and ranges, and `size_t` is used for byte or character counts.

Internally, GMP data types such as `mpz_t` are defined as one-element arrays, whose element type is part of the GMP internals (see Internals).

When an array is used as a function argument in C, it is not passed by value, instead its value is a pointer to the first element. In C jargon, this is sometimes referred to as the array "decaying" to a pointer. For GMP types like `mpz_t`, that means that the function called gets a pointer to the caller’s `mpz_t` value, which is why no explicit `&` operator is needed when passing output arguments (see Parameter Conventions).

GMP defines names for these pointer types, e.g., `mpz_ptr` corresponding to `mpz_t`, and `mpz_srcptr` corresponding to `const mpz_t`. Most functions don’t need to use these pointer types directly; it works fine to declare a function using the `mpz_t` or `const mpz_t` as the argument types, the same "pointer decay" happens in the background regardless.

Occasionally, it is useful to manipulate pointers directly, e.g., to conditionally swap references to a function’s inputs without changing the values as seen by the caller, or returning a pointer to an `mpz_t` which is part of a larger structure. For these cases, the pointer types are necessary. And a `mpz_ptr` can be passed as argument to any GMP function declared to take an `mpz_t` argument.

Their definition is equivalent to the following code, which is given for illustratory purposes only:

        typedef foo_internal foo_t[1];
        typedef foo_internal * foo_ptr;
        typedef const foo_internal * foo_srcptr;

The following pointer types are defined by GMP:

- `mpz_ptr` for pointers to the element type in `mpz_t`
- `mpz_srcptr` for `const` pointers to the element type in `mpz_t`
- `mpq_ptr` for pointers to the element type in `mpq_t`
- `mpq_srcptr` for `const` pointers to the element type in `mpq_t`
- `mpf_ptr` for pointers to the element type in `mpf_t`
- `mpf_srcptr` for `const` pointers to the element type in `mpf_t`
- `gmp_randstate_ptr` for pointers to the element type in `gmp_randstate_t`
- `gmp_randstate_srcptr` for `const` pointers to the element type in `gmp_randstate_t`

### 3.3 Function Classes ¶

There are six classes of functions in the GMP library:

1. Functions for signed integer arithmetic, with names beginning with `mpz_`. The associated type is `mpz_t`. There are about 150 functions in this class. (see Integer Functions)
2. Functions for rational number arithmetic, with names beginning with `mpq_`. The associated type is `mpq_t`. There are about 35 functions in this class, but the integer functions can be used for arithmetic on the numerator and denominator separately. (see Rational Number Functions)
3. Functions for floating-point arithmetic, with names beginning with `mpf_`. The associated type is `mpf_t`. There are about 70 functions in this class. (see Floating-point Functions)
4. Fast low-level functions that operate on natural numbers. These are used by the functions in the preceding groups, and you can also call them directly from very time-critical user programs. These functions’ names begin with `mpn_`. The associated type is array of `mp_limb_t`. There are about 60 (hard-to-use) functions in this class. (see Low-level Functions)
5. Miscellaneous functions. Functions for setting up custom allocation and functions for generating random numbers. (see Custom Allocation, and see Random Number Functions)

### 3.4 Variable Conventions ¶

GMP functions generally have output arguments before input arguments. This notation is by analogy with the assignment operator.

GMP lets you use the same variable for both input and output in one call. For example, the main function for integer multiplication, `mpz_mul`, can be used to square `x` and put the result back in `x` with

    mpz_mul (x, x, x);

Before you can assign to a GMP variable, you need to initialize it by calling one of the special initialization functions. When you’re done with a variable, you need to clear it out, using one of the functions for that purpose. Which function to use depends on the type of variable. See the chapters on integer functions, rational number functions, and floating-point functions for details.

A variable should only be initialized once, or at least cleared between each initialization. After a variable has been initialized, it may be assigned to any number of times.

For efficiency reasons, avoid excessive initializing and clearing. In general, initialize near the start of a function and clear near the end. For example,

    void
    foo (void)
    {
      mpz_t  n;
      int    i;
      mpz_init (n);
      for (i = 1; i < 100; i++)
        {
          mpz_mul (n, ...);
          mpz_fdiv_q (n, ...);
          ...
        }
      mpz_clear (n);
    }

GMP types like `mpz_t` are implemented as one-element arrays of certain structures. Declaring a variable creates an object with the fields GMP needs, but variables are normally manipulated by using the pointer to the object. The appropriate pointer types (Nomenclature and Types) may be used to explicitly manipulate the pointer. For both behavior and efficiency reasons, it is discouraged to make copies of the GMP object itself (either directly or via aggregate objects containing such GMP objects). If copies are done, all of them must be used read-only; using a copy as the output of some function will invalidate all the other copies. Note that the actual fields in each `mpz_t` etc are for internal use only and should not be accessed directly by code that expects to be compatible with future GMP releases.

### 3.5 Parameter Conventions ¶

When a GMP variable is used as a function parameter, it’s effectively a call-by-reference, meaning that when the function stores a value there it will change the original in the caller. Parameters which are input-only can be designated `const` to provoke a compiler error or warning on attempting to modify them.

When a function is going to return a GMP result, it should designate a parameter that it sets, like the library functions do. More than one value can be returned by having more than one output parameter, again like the library functions. A `return` of an `mpz_t` etc doesn’t return the object, only a pointer, and this is almost certainly not what’s wanted.

Here’s an example accepting an `mpz_t` parameter, doing a calculation, and storing the result to the indicated parameter.

    void
    foo (mpz_t result, const mpz_t param, unsigned long n)
    {
      unsigned long  i;
      mpz_mul_ui (result, param, n);
      for (i = 1; i < n; i++)
        mpz_add_ui (result, result, i*7);
    }
    int
    main (void)
    {
      mpz_t  r, n;
      mpz_init (r);
      mpz_init_set_str (n, "123456", 0);
      foo (r, n, 20L);
      gmp_printf ("%Zd\n", r);
      return 0;
    }

Our function `foo` works even if its caller passes the same variable for `param` and `result`, just like the library functions. But sometimes it’s tricky to make that work, and an application might not want to bother supporting that sort of thing.

Since GMP types are implemented as one-element arrays, using a GMP variable as a parameter passes a pointer to the object. Hence the call-by-reference. A more explicit (and equivalent) prototype for our function `foo` could be:

    void foo (mpz_ptr result, mpz_srcptr param, unsigned long n);

### 3.6 Memory Management ¶

The GMP types like `mpz_t` are small, containing only a couple of sizes, and pointers to allocated data. Once a variable is initialized, GMP takes care of all space allocation. Additional space is allocated whenever a variable doesn’t have enough.

`mpz_t` and `mpq_t` variables never reduce their allocated space. Normally this is the best policy, since it avoids frequent reallocation. Applications that need to return memory to the heap at some particular point can use `mpz_realloc2`, or clear variables no longer needed.

`mpf_t` variables, in the current implementation, use a fixed amount of space, determined by the chosen precision and allocated at initialization, so their size doesn’t change.

All memory is allocated using `malloc` and friends by default, but this can be changed, see Custom Allocation. Temporary memory on the stack is also used (via `alloca`), but this can be changed at build-time if desired, see Build Options.

### 3.7 Reentrancy ¶

GMP is reentrant and thread-safe, with some exceptions:

- If configured with `--enable-alloca=malloc-notreentrant` (or with `--enable-alloca=notreentrant` when `alloca` is not available), then naturally GMP is not reentrant.
- `mpf_set_default_prec` and `mpf_init` use a global variable for the selected precision. `mpf_init2` can be used instead, and in the C++ interface an explicit precision to the `mpf_class` constructor.
- `mpz_random` and the other old random number functions use a global random state and are hence not reentrant. The newer random number functions that accept a `gmp_randstate_t` parameter can be used instead.
- `gmp_randinit` (obsolete) returns an error indication through a global variable, which is not thread safe. Applications are advised to use `gmp_randinit_default` or `gmp_randinit_lc_2exp` instead.
- `mp_set_memory_functions` uses global variables to store the selected memory allocation functions.
- If the memory allocation functions set by a call to `mp_set_memory_functions` (or `malloc` and friends by default) are not reentrant, then GMP will not be reentrant either.
- If the standard I/O functions such as `fwrite` are not reentrant then the GMP I/O functions using them will not be reentrant either.
- It’s safe for two threads to read from the same GMP variable simultaneously, but it’s not safe for one to read while another might be writing, nor for two threads to write simultaneously. It’s not safe for two threads to generate a random number from the same `gmp_randstate_t` simultaneously, since this involves an update of that variable.

### 3.8 Useful Macros and Constants ¶

Global Constant: `const int` mp_bits_per_limb ¶

  The number of bits per limb.

Macro: __GNU_MP_VERSION ¶
Macro: __GNU_MP_VERSION_MINOR ¶
Macro: __GNU_MP_VERSION_PATCHLEVEL ¶

  The major and minor GMP version, and patch level, respectively, as integers. For GMP i.j, these numbers will be i, j, and 0, respectively. For GMP i.j.k, these numbers will be i, j, and k, respectively.

Global Constant: `const char * const` gmp_version ¶

  The GMP version number, as a null-terminated string, in the form “i.j.k”. This release is `"6.3.0"`. Note that the format “i.j” was used, before version 4.3.0, when k was zero.

Macro: __GMP_CC ¶
Macro: __GMP_CFLAGS ¶

  The compiler and compiler flags, respectively, used when compiling GMP, as strings.

### 3.9 Compatibility with older versions ¶

This version of GMP is upwardly binary compatible with all 5.x, 4.x, and 3.x versions, and upwardly compatible at the source level with all 2.x versions, with the following exceptions.

- `mpn_gcd` had its source arguments swapped as of GMP 3.0, for consistency with other `mpn` functions.
- `mpf_get_prec` counted precision slightly differently in GMP 3.0 and 3.0.1, but in 3.1 reverted to the 2.x style.
- `mpn_bdivmod`, documented as preliminary in GMP 4, has been removed.

There are a number of compatibility issues between GMP 1 and GMP 2 that of course also apply when porting applications from GMP 1 to GMP 5. Please see the GMP 2 manual for details.

### 3.10 Demonstration programs ¶

The `demos` subdirectory has some sample programs using GMP. These aren’t built or installed, but there’s a `Makefile` with rules for them. For instance,

    make pexpr
    ./pexpr 68^975+10

The following programs are provided

- ‘`pexpr`’ is an expression evaluator, the program used on the GMP web page.
- The ‘`calc`’ subdirectory has a similar but simpler evaluator using `lex` and `yacc`.
- The ‘`expr`’ subdirectory is yet another expression evaluator, a library designed for ease of use within a C program. See `demos/expr/README` for more information.
- ‘`factorize`’ is a Pollard-Rho factorization program.
- ‘`isprime`’ is a command-line interface to the `mpz_probab_prime_p` function.
- ‘`primes`’ counts or lists primes in an interval, using a sieve.
- ‘`qcn`’ is an example use of `mpz_kronecker_ui` to estimate quadratic class numbers.
- The ‘`perl`’ subdirectory is a comprehensive perl interface to GMP. See `demos/perl/INSTALL` for more information. Documentation is in POD format in `demos/perl/GMP.pm`.

As an aside, consideration has been given at various times to some sort of expression evaluation within the main GMP library. Going beyond something minimal quickly leads to matters like user-defined functions, looping, fixnums for control variables, etc, which are considered outside the scope of GMP (much closer to language interpreters or compilers, See Language Bindings). Something simple for program input convenience may yet be a possibility, a combination of the `expr` demo and the `pexpr` tree back-end perhaps. But for now the above evaluators are offered as illustrations.

### 3.11 Efficiency ¶

Small Operands ¶

  On small operands, the time for function call overheads and memory allocation can be significant in comparison to actual calculation. This is unavoidable in a general purpose variable precision library, although GMP attempts to be as efficient as it can on both large and small operands.

Static Linking ¶

  On some CPUs, in particular the x86s, the static `libgmp.a` should be used for maximum speed, since the PIC code in the shared `libgmp.so` will have a small overhead on each function call and global data address. For many programs this will be insignificant, but for long calculations there’s a gain to be had.

Initializing and Clearing ¶

  Avoid excessive initializing and clearing of variables, since this can be quite time consuming, especially in comparison to otherwise fast operations like addition.

  A language interpreter might want to keep a free list or stack of initialized variables ready for use. It should be possible to integrate something like that with a garbage collector too.

Reallocations ¶

  An `mpz_t` or `mpq_t` variable used to hold successively increasing values will have its memory repeatedly `realloc`ed, which could be quite slow or could fragment memory, depending on the C library. If an application can estimate the final size then `mpz_init2` or `mpz_realloc2` can be called to allocate the necessary space from the beginning (see Initialization Functions).

  It doesn’t matter if a size set with `mpz_init2` or `mpz_realloc2` is too small, since all functions will do a further reallocation if necessary. Badly overestimating memory required will waste space though.

`2exp` Functions ¶

  It’s up to an application to call functions like `mpz_mul_2exp` when appropriate. General purpose functions like `mpz_mul` make no attempt to identify powers of two or other special forms, because such inputs will usually be very rare and testing every time would be wasteful.

`ui` and `si` Functions ¶

  The `ui` functions and the small number of `si` functions exist for convenience and should be used where applicable. But if for example an `mpz_t` contains a value that fits in an `unsigned long` there’s no need to extract it and call a `ui` function, just use the regular `mpz` function.

In-Place Operations ¶

  `mpz_abs`, `mpq_abs`, `mpf_abs`, `mpz_neg`, `mpq_neg` and `mpf_neg` are fast when used for in-place operations like `mpz_abs(x,x)`, since in the current implementation only a single field of `x` needs changing. On suitable compilers (GCC for instance) this is inlined too.

  `mpz_add_ui`, `mpz_sub_ui`, `mpf_add_ui` and `mpf_sub_ui` benefit from an in-place operation like `mpz_add_ui(x,x,y)`, since usually only one or two limbs of `x` will need to be changed. The same applies to the full precision `mpz_add` etc if `y` is small. If `y` is big then cache locality may be helped, but that’s all.

  `mpz_mul` is currently the opposite, a separate destination is slightly better. A call like `mpz_mul(x,x,y)` will, unless `y` is only one limb, make a temporary copy of `x` before forming the result. Normally that copying will only be a tiny fraction of the time for the multiply, so this is not a particularly important consideration.

  `mpz_set`, `mpq_set`, `mpq_set_num`, `mpf_set`, etc, make no attempt to recognise a copy of something to itself, so a call like `mpz_set(x,x)` will be wasteful. Naturally that would never be written deliberately, but if it might arise from two pointers to the same object then a test to avoid it might be desirable.

      if (x != y)
        mpz_set (x, y);

  Note that it’s never worth introducing extra `mpz_set` calls just to get in-place operations. If a result should go to a particular variable then just direct it there and let GMP take care of data movement.

Divisibility Testing (Small Integers) ¶

  `mpz_divisible_ui_p` and `mpz_congruent_ui_p` are the best functions for testing whether an `mpz_t` is divisible by an individual small integer. They use an algorithm which is faster than `mpz_tdiv_ui`, but which gives no useful information about the actual remainder, only whether it’s zero (or a particular value).

  However when testing divisibility by several small integers, it’s best to take a remainder modulo their product, to save multi-precision operations. For instance to test whether a number is divisible by 23, 29 or 31 take a remainder modulo 23*29*31 = 20677 and then test that.

  The division functions like `mpz_tdiv_q_ui` which give a quotient as well as a remainder are generally a little slower than the remainder-only functions like `mpz_tdiv_ui`. If the quotient is only rarely wanted then it’s probably best to just take a remainder and then go back and calculate the quotient if and when it’s wanted (`mpz_divexact_ui` can be used if the remainder is zero).

Rational Arithmetic ¶

  The `mpq` functions operate on `mpq_t` values with no common factors in the numerator and denominator. Common factors are checked-for and cast out as necessary. In general, cancelling factors every time is the best approach since it minimizes the sizes for subsequent operations.

  However, applications that know something about the factorization of the values they’re working with might be able to avoid some of the GCDs used for canonicalization, or swap them for divisions. For example when multiplying by a prime it’s enough to check for factors of it in the denominator instead of doing a full GCD. Or when forming a big product it might be known that very little cancellation will be possible, and so canonicalization can be left to the end.

  The `mpq_numref` and `mpq_denref` macros give access to the numerator and denominator to do things outside the scope of the supplied `mpq` functions. See Applying Integer Functions to Rationals.

  The canonical form for rationals allows mixed-type `mpq_t` and integer additions or subtractions to be done directly with multiples of the denominator. This will be somewhat faster than `mpq_add`. For example,

      /* mpq increment */
      mpz_add (mpq_numref(q), mpq_numref(q), mpq_denref(q));
      /* mpq += unsigned long */
      mpz_addmul_ui (mpq_numref(q), mpq_denref(q), 123UL);
      /* mpq -= mpz */
      mpz_submul (mpq_numref(q), mpq_denref(q), z);

Number Sequences ¶

  Functions like `mpz_fac_ui`, `mpz_fib_ui` and `mpz_bin_uiui` are designed for calculating isolated values. If a range of values is wanted it’s probably best to get a starting point and iterate from there.

Text Input/Output ¶

  Hexadecimal or octal are suggested for input or output in text form. Power-of-2 bases like these can be converted much more efficiently than other bases, like decimal. For big numbers there’s usually nothing of particular interest to be seen in the digits, so the base doesn’t matter much.

  Maybe we can hope octal will one day become the normal base for everyday use, as proposed by King Charles XII of Sweden and later reformers.

### 3.12 Debugging ¶

Stack Overflow ¶

  Depending on the system, a segmentation violation or bus error might be the only indication of stack overflow. See ‘`--enable-alloca`’ choices in Build Options, for how to address this.

  In new enough versions of GCC, ‘`-fstack-check`’ may be able to ensure an overflow is recognised by the system before too much damage is done, or ‘`-fstack-limit-symbol`’ or ‘`-fstack-limit-register`’ may be able to add checking if the system itself doesn’t do any (see Options for Code Generation in Using the GNU Compiler Collection (GCC)). These options must be added to the ‘`CFLAGS`’ used in the GMP build (see Build Options), adding them just to an application will have no effect. Note also they’re a slowdown, adding overhead to each function call and each stack allocation.

Heap Problems ¶

  The most likely cause of application problems with GMP is heap corruption. Failing to `init` GMP variables will have unpredictable effects, and corruption arising elsewhere in a program may well affect GMP. Initializing GMP variables more than once or failing to clear them will cause memory leaks.

  In all such cases a `malloc` debugger is recommended. On a GNU or BSD system the standard C library `malloc` has some diagnostic facilities, see Allocation Debugging in The GNU C Library Reference Manual, or ‘`man 3 malloc`’. Other possibilities, in no particular order, include

      http://cs.ecs.baylor.edu/~donahoo/tools/ccmalloc/
      http://dmalloc.com/
      https://wiki.gnome.org/Apps/MemProf

  The GMP default allocation routines in `memory.c` also have a simple sentinel scheme which can be enabled with `#define DEBUG` in that file. This is mainly designed for detecting buffer overruns during GMP development, but might find other uses.

Stack Backtraces ¶

  On some systems the compiler options GMP uses by default can interfere with debugging. In particular on x86 and 68k systems ‘`-fomit-frame-pointer`’ is used and this generally inhibits stack backtracing. Recompiling without such options may help while debugging, though the usual caveats about it potentially moving a memory problem or hiding a compiler bug will apply.

GDB, the GNU Debugger ¶

  A sample `.gdbinit` is included in the distribution, showing how to call some undocumented dump functions to print GMP variables from within GDB. Note that these functions shouldn’t be used in final application code since they’re undocumented and may be subject to incompatible changes in future versions of GMP.

Source File Paths

  GMP has multiple source files with the same name, in different directories. For example `mpz`, `mpq` and `mpf` each have an `init.c`. If the debugger can’t already determine the right one it may help to build with absolute paths on each C file. One way to do that is to use a separate object directory with an absolute path to the source directory.

      cd /my/build/dir
      /my/source/dir/gmp-6.3.0/configure

  This works via `VPATH`, and might require GNU `make`. Alternately it might be possible to change the `.c.lo` rules appropriately.

Assertion Checking ¶

  The build option `--enable-assert` is available to add some consistency checks to the library (see Build Options). These are likely to be of limited value to most applications. Assertion failures are just as likely to indicate memory corruption as a library or compiler bug.

  Applications using the low-level `mpn` functions, however, will benefit from `--enable-assert` since it adds checks on the parameters of most such functions, many of which have subtle restrictions on their usage. Note however that only the generic C code has checks, not the assembly code, so `--disable-assembly` should be used for maximum checking.

Temporary Memory Checking

  The build option `--enable-alloca=debug` arranges that each block of temporary memory in GMP is allocated with a separate call to `malloc` (or the allocation function set with `mp_set_memory_functions`).

  This can help a malloc debugger detect accesses outside the intended bounds, or detect memory not released. In a normal build, on the other hand, temporary memory is allocated in blocks which GMP divides up for its own use, or may be allocated with a compiler builtin `alloca` which will go nowhere near any malloc debugger hooks.

Maximum Debuggability

  To summarize the above, a GMP build for maximum debuggability would be

      ./configure --disable-shared --enable-assert \
        --enable-alloca=debug --disable-assembly CFLAGS=-g

  For C++, add ‘`--enable-cxx CXXFLAGS=-g`’.

Checker ¶

  The GCC checker (https://savannah.nongnu.org/projects/checker/) can be used with GMP. It contains a stub library which means GMP applications compiled with checker can use a normal GMP build.

  A build of GMP with checking within GMP itself can be made. This will run very very slowly. On GNU/Linux for example,

      ./configure --disable-assembly CC=checkergcc

  `--disable-assembly` must be used, since the GMP assembly code doesn’t support the checking scheme. The GMP C++ features cannot be used, since current versions of checker (0.9.9.1) don’t yet support the standard C++ library.

Valgrind ¶

  Valgrind (http://valgrind.org/) is a memory checker for x86, ARM, MIPS, PowerPC, and S/390. It translates and emulates machine instructions to do strong checks for uninitialized data (at the level of individual bits), memory accesses through bad pointers, and memory leaks.

  Valgrind does not always support every possible instruction, in particular ones recently added to an ISA. Valgrind might therefore be incompatible with a recent GMP or even a less recent GMP which is compiled using a recent GCC.

  GMP’s assembly code sometimes promotes a read of the limbs to some larger size, for efficiency. GMP will do this even at the start and end of a multilimb operand, using naturally aligned operations on the larger type. This may lead to benign reads outside of allocated areas, triggering complaints from Valgrind. Valgrind’s option ‘`--partial-loads-ok=yes`’ should help.

Other Problems

  Any suspected bug in GMP itself should be isolated to make sure it’s not an application problem, see Reporting Bugs.

### 3.13 Profiling ¶

Running a program under a profiler is a good way to find where it’s spending most time and where improvements can be best sought. The profiling choices for a GMP build are as follows.

‘`--disable-profiling`’

  The default is to add nothing special for profiling.

  It should be possible to just compile the mainline of a program with `-p` and use `prof` to get a profile consisting of timer-based sampling of the program counter. Most of the GMP assembly code has the necessary symbol information.

  This approach has the advantage of minimizing interference with normal program operation, but on most systems the resolution of the sampling is quite low (10 milliseconds for instance), requiring long runs to get accurate information.

‘`--enable-profiling=prof`’ ¶

  Build with support for the system `prof`, which means ‘`-p`’ added to the ‘`CFLAGS`’.

  This provides call counting in addition to program counter sampling, which allows the most frequently called routines to be identified, and an average time spent in each routine to be determined.

  The x86 assembly code has support for this option, but on other processors the assembly routines will be as if compiled without ‘`-p`’ and therefore won’t appear in the call counts.

  On some systems, such as GNU/Linux, ‘`-p`’ in fact means ‘`-pg`’ and in this case ‘`--enable-profiling=gprof`’ described below should be used instead.

‘`--enable-profiling=gprof`’ ¶

  Build with support for `gprof`, which means ‘`-pg`’ added to the ‘`CFLAGS`’.

  This provides call graph construction in addition to call counting and program counter sampling, which makes it possible to count calls coming from different locations. For example the number of calls to `mpn_mul` from `mpz_mul` versus the number from `mpf_mul`. The program counter sampling is still flat though, so only a total time in `mpn_mul` would be accumulated, not a separate amount for each call site.

  The x86 assembly code has support for this option, but on other processors the assembly routines will be as if compiled without ‘`-pg`’ and therefore not be included in the call counts.

  On x86 and m68k systems ‘`-pg`’ and ‘`-fomit-frame-pointer`’ are incompatible, so the latter is omitted from the default flags in that case, which might result in poorer code generation.

  Incidentally, it should be possible to use the `gprof` program with a plain ‘`--enable-profiling=prof`’ build. But in that case only the ‘`gprof -p`’ flat profile and call counts can be expected to be valid, not the ‘`gprof -q`’ call graph.

‘`--enable-profiling=instrument`’ ¶

  Build with the GCC option ‘`-finstrument-functions`’ added to the ‘`CFLAGS`’ (see Options for Code Generation in Using the GNU Compiler Collection (GCC)).

  This inserts special instrumenting calls at the start and end of each function, allowing exact timing and full call graph construction.

  This instrumenting is not normally a standard system feature and will require support from an external library, such as

      https://sourceforge.net/projects/fnccheck/

  This should be included in ‘`LIBS`’ during the GMP configure so that test programs will link. For example,

      ./configure --enable-profiling=instrument LIBS=-lfc

  On a GNU system the C library provides dummy instrumenting functions, so programs compiled with this option will link. In this case it’s only necessary to ensure the correct library is added when linking an application.

  The x86 assembly code supports this option, but on other processors the assembly routines will be as if compiled without ‘`-finstrument-functions`’ meaning time spent in them will effectively be attributed to their caller.

### 3.14 Autoconf ¶

Autoconf based applications can easily check whether GMP is installed. The only thing to be noted is that GMP library symbols from version 3 onwards have prefixes like `__gmpz`. The following therefore would be a simple test,

    AC_CHECK_LIB(gmp, __gmpz_init)

This just uses the default `AC_CHECK_LIB` actions for found or not found, but an application that must have GMP would want to generate an error if not found. For example,

    AC_CHECK_LIB(gmp, __gmpz_init, ,
      [AC_MSG_ERROR([GNU MP not found, see https://gmplib.org/])])

If functions added in some particular version of GMP are required, then one of those can be used when checking. For example `mpz_mul_si` was added in GMP 3.1,

    AC_CHECK_LIB(gmp, __gmpz_mul_si, ,
      [AC_MSG_ERROR(
      [GNU MP not found, or not 3.1 or up, see https://gmplib.org/])])

An alternative would be to test the version number in `gmp.h` using say `AC_EGREP_CPP`. That would make it possible to test the exact version, if some particular sub-minor release is known to be necessary.

In general it’s recommended that applications should simply demand a new enough GMP rather than trying to provide supplements for features not available in past versions.

Occasionally an application will need or want to know the size of a type at configuration or preprocessing time, not just with `sizeof` in the code. This can be done in the normal way with `mp_limb_t` etc, but GMP 4.0 or up is best for this, since prior versions needed certain ‘`-D`’ defines on systems using a `long long` limb. The following would suit Autoconf 2.50 or up,

    AC_CHECK_SIZEOF(mp_limb_t, , [#include <gmp.h>])

### 3.15 Emacs ¶

`C-h C-i` (`info-lookup-symbol`) is a good way to find documentation on C functions while editing (see Info Documentation Lookup in The Emacs Editor).

The GMP manual can be included in such lookups by putting the following in your `.emacs`,

    (eval-after-load "info-look"
      '(let ((mode-value (assoc 'c-mode (assoc 'symbol info-lookup-alist))))
         (setcar (nthcdr 3 mode-value)
                 (cons '("(gmp)Function Index" nil "^ -.* " "\\>")
                       (nth 3 mode-value)))))