This manual describes how to use the GMP compiler, version 1.0.0 (23 December 2006)

Copyright (C) 2006 Free Software Foundation, Inc.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover Texts being "A GNU Manual", and with the Back-Cover Texts being "You have freedom to copy and modify this GNU Manual, like GNU software".

The gmpc tool simplifies the use of GMP, the GNU multiple precision library. It scans a C source file for specially marked GMPS arithmetic expressions and replaces them with plain C.

The abbreviation gmpc stands for GMP compiler, or alternatively
GMPS-to-C compiler. GMPS arithmetic expressions are straightforward
infix expressions which transparently support the special types
`mpq_t`

, `mpz_t`

and `mpf_t`

as
defined by GMP. GMPS means, rather unimaginatively, `GMP
script'.

No dependencies are added to the resulting C source, so there is no need to include additional header files or link with special libraries other than GMP.

The gmpc distribution can be downloaded here:

On UNIX-like systems, a basic build can be done with

./configure make

The `configure`

script has a lot of useful options.
Try `./configure --help`

to see them. Installation can
be done with

make install

Regression tests are accessible through the `check`

target.

make check

The `tests`

directory contains the `*.gmpc` files under test.

To translate a
`.gmpc`

file to C source, at least the input and output
files must be given. The most concise invocation would look like
this:

gmpc -o foo.c foo.gmpc

This will translate `foo.gmpc` into `foo.c`.

It is highly recommended to enable all warnings with the
`-Wall` switch:

gmpc -Wall -o foo.gmpc foo.c

Other switches can be used to change the default behaviour of gmpc. They are listed in the following sections.

The generated C
code usually contains numerical constants. The output base in which
all `mpq_t`

, `mpz_t`

and `mpf_t`

constants are represented can be set with the `-fbase` switch. The following example will
cause all constants to be hexadecimal.

gmpc -fbase=16 -o foo.c foo.gmpc

The default base is 10. If you are not interested in generating human-readable code, a power of 2 (e.g. 16) may be more space and time efficient.

The
generated C code may contain `mpf_t`

constants. The
`-ffloat-digits` option can
be used to set the number of digits. The following example will set
the number of `mpf_t`

digits to 120.

gmpc -ffloat-digits=120 -o foo.c foo.gmpc

Note that the number of digits in `double`

(the
native C type) constants is controlled by the
`-fdouble-format`

switch.

The
generated C code may contain `double`

constants. The
`-fdouble-format` option can
be used to set the formatting of such constants using a
`printf`

-like format specifier. The following example
will set the number of `double`

digits to 20, with
trailing zeros removed.

gmpc -fdouble-format=%.20g -o foo.c foo.gmpc

The default value is `%24.24e`

.

gmpc uses
GMP to evaluate constant expressions. The default precision for
`mpf_t`

calculations is set with `-fprecision`. This is the value that is
passed to `mpf_set_default_prec`

internally. Its default
value is ```
<float digits> * log <base> / log
<2> + 1
```

.

The generated C
code may contain declarations and definitions of temporary
variables. In order to avoid name space pollution, a suitable
prefix for all symbols can be set with the `-fprefix` option.

The following example will prefix all symbols with
`yy`

.

gmpc -fprefix=yy -o foo.c foo.gmpc

The default value is `gmps`

.

Using a variable before it is defined (using either
`import`

or `var`

GMPS statements) will
automatically create it. To guard against typos or the creation of
variables of unexpected types, gmpc has the option
`-Wundefined-variables` to
show a warning when a variable is created automatically.

This option is implied by the `-Wall` switch.

In
order to be useful, a `.gmpc`

file should contain GMPS
statements for at least the following 4 sections:

The option `-Wmissing-sections` will cause gmpc to emit a
warning for each missing section.

This option is implied by the `-Wall` switch.

Unused
expressions are wasteful, even if they have useful side-effects. In
the following example, the assignment to `dr`

is carried
out, but the result of `+1`

is not used.

%% mpf_t 1 + (dr = mpf_sqrt(dx*dx + dy*dy));

If the option `-Wunused-expressions` is used, the first
`+`

will trigger a warning.

This option is implied by the `-Wall` switch.

The option
`-Wall` enables all
warnings, i.e. `-Wundefined-variables`, `-Wunused-expressions` and `-Wmissing-sections`.

The
option `-fno-linemarkers`
inhibits the inclusion of `#line xxx`

lines in the
generated C code.

The
option `-fdump-prototypes`
causes gmpc to list all supported GMP functions, and exit.

The option
`-version` causes gmpc to
print its version number on stdout, and exit.

The option
`-help` causes gmpc to print
a short help message on stdout, and exit.

GMPS statements are the statements
that are actually seen by gmpc. GMPS statements are embedded in C
code. To distinguish GMPS from C, a GMPS line starts with
`%%`

. Lines that do not start with this special token
are considered C source, and copied to the output file without any
interpretation.

GMPS lines are usually replaced with generated C source, although sometimes they are just there to tell gmpc something.

Arithmetic expressions can freely mix `mpq_t`

,
`mpz_t`

and `mpf_t`

variables and constants
with the native C types `int`

, `long int`

and
`unsigned long int`

.

There are no control statements like branches and loops in GMPS. These things should be handled in C.

The next sections deal with GMPS in more detail.

Since gmpc ignores C code lines, using C-style comments to comment out sections of code will not prevent gmpc from interpreting GMPS statements.

In the next example, gmpc will still create code for the
`init`

, `body`

and `cleanup`

sections, which end up as C-comments.

int main(void) { /* %% init; foo_func(); %% mpq_t y = (2/3)*x*x + 3*x - 1/12; %% cleanup; */ return 0; }

Changing the comments to `#if 0`

...
`#endif`

would have the same effect. GMPS does support
C-style comments, however. The next example does not create
`init`

, `body`

and `cleanup`

sections.

int main(void) { /* %% /* init; foo_func(); %% mpq_t y = (2/3)*x*x + 3*x - 1/12; %% cleanup; */ */ return 0; }

Expressions that are translated
by gmpc typically need temporary variables and constants. gmpc adds
declarations for all temporaries and constants to the declarations
section. In the eventual output, the `declarations`

keyword is replaced by the full list of C declarations. It can be
placed either at file scope or at function scope, although the
latter only makes sense in C function that contains all 4
obligatory sections `declarations`

, `init`

,
`body`

and `cleanup`

.

At file scope, a `declarations`

section looks like
this:

%% declarations; int main(void) { return 0; }

It is also possible to make all C declarations
`static`

with `%% static declarations;`

.

Expressions that are translated by gmpc typically need temporary
variables and constants. The `init`

keyword is replaced
by the necessary C initialisations. It usually consists of a
sequence of GMP calls like `mpz_init()`

and
`mpf_set_str()`

.

In GMPS, an `init`

section looks like this:

%% init;

Your code should be set up so that the generated C code is run exactly one, at startup.

Its counterpart is the `cleanup`

section.

Expressions that are translated by
gmpc typically need temporary variables and constants. The
`cleanup`

keyword is replaced by the necessary C cleanup
actions. It usually consists of a sequence of GMP calls like
`mpz_clear()`

.

In GMPS, a `cleanup`

section looks like this:

%% cleanup;

If you do not want to leave any allocated memory behind, your code should be set up so that the generated C code is run exactly one, during shutdown.

GMPS has its own name space. If
you want to interface with C code generated by gmpc, you may want
to import variables from your C program into GMPS's name space.
This can be done with the `import`

keyword.

In the next example, `x`

and `y`

are
imported.

void poly(mpq_t y, mpq_t x) { %% import mpq_t x, y; %% mpq_t y = (x+1)*(x-1)*x/6 + 1; }

Note that, since GMPS has only one name space, `x`

and `y`

are visible in all subsequent `body`

sections. In fact, since the `import`

keyword is not
replaced by C code, it can be placed anywhere in the file, as long
as it comes before the `body`

section that needs the
variables.

gmpc will not create any code for the `declarations`

,
`init`

and `cleanup`

sections if a variable
is imported – it will just assume that the variable is
available and ready.

Use the `var`

keyword if you want to leave
initialisation and cleanup to gmpc. For parameters, such as in the
example, `import`

should be used.

Using a variable before it is
defined will automatically create it. To force the creation of a
variable of a certain type, or to prevent warnings about undefined
variables when `-Wundefined-variables` is used, a variable
can be defined explicitly with the `var`

keyword.

In the following example, `r2`

is defined
explicitly.

void poly(mpq_t y, mpq_t x) { %% import mpq_t x, y; %% var mpq_t r2; %% mpq_t { %% r2 = x*x + y*y; %% y = (x+1)*(x-1)*x/6 + 1; %% } gmp_printf("r2 = %Qd\n", r2); }

This code fragment would also work without the `var`

statement.

Unlike imported variables, defined variables are logically owned
by GMPS, but available to the C program. gmpc will create code for
the `declarations`

, `init`

and
`cleanup`

sections.

The same is true for variables that are neither defined nor imported.

The `body`

section is where
most of the work is done. It declares a default type, and contains
one ore more arithmetic expressions that are translated into C
code.

In the following example, the `body`

section defines
two expressions with a default type `mpq_t`

.

void poly(mpq_t y, mpq_t x) { %% import mpq_t x, y; %% body mpq_t { %% r2 = x*x + y*y; %% y = (x+1)*(x-1)*x/6 + 1; %% } gmp_printf("r2 = %Qd\n", r2); }

The `body`

keyword is optional. If only one
expression is defined, the braces can be omitted:

void poly(mpq_t y, mpq_t x) { %% import mpq_t x, y; %% mpq_t y = (x+1)*(x-1)*x/6 + 1; }

Or, since GMPS is a free-format language:

void poly(mpq_t y, mpq_t x) { %% import mpq_t x, y; %% mpq_t %% y = (x+1)*(x-1)*x/6 + 1; }

GMPS expressions are the arithmetic
expressions that are used in `body`

sections. The
ability to translate them into plain C is the core feature of
gmpc.

Arithmetic expressions are infix, and C-like, although some things are done differently to keep the expressions as clean as possible.

Every expression has a default
type, which is defined by the `body`

section that
contains it. This type can be `mpq_t`

,
`mpz_t`

or `mpf_t`

.

The main application of the default type is in constants. In the
next example, all constants are `mpq_t`

constants.

mpq_t q = 1/2 + 1/3 + 1/4;

Default types also play an important part in the creation of undefined variables, and in implicit type conversions.

The type of an undefined variable is determined by the following rules:

- A
*reference*to an undefined scalar variable will cause the creation of a variable of the default type. This variable will be initialised by GMP and therefore have a defined`0`

value. - An
*assignment*to an undefined variable will trigger the creation of a variable whose type is equal to that of the right-hand side of the assignment.

**Note** 1: Array elements cannot be created
automatically. They must be imported.

**Note** 2: Compound assignments like ```
y +=
x;
```

are treated as a reference followed by an assignment, so
the default type will be applied if `y`

is
undefined.

If a type conversion is needed, a C-like cast expression can be used. However, in some cases GMPS allows type mismatches and silently applies conversions.

- Function parameters that are `pass by value' are automatically converted.
- In assignments, the right-hand side is automatically converted to fit the variable on the left-hand side.

Furthermore, some operators expect operands of a certain type. Operands will be converted implicitly in the following cases:

`<<`

and`>>`

expect`unsigned long int`

right-hand side operands. The resulting type is equal to that of the left-hand side operand.`*`

,`/`

,`+`

and`-`

expect both operands to have the same type. An appropriate mixed-type GMP function may be used, if available. For example,`(mpz_t)a + (unsigned long int)b`

will result in an`mpz_add_ui()`

function call. If no appropriate GMP function is found, both operands will be converted to the default type.- The relational operators
`<`

,`<=`

,`>`

,`>=`

,`==`

and`!=`

convert their operands to the default type. If an appropriate mixed-type GMP function is found, it will be used instead. - The boolean operators
`&&`

,`||`

and`!`

expect`int`

operands. Their result is an`int`

.

As an exception, the bitwise operators `&`

,
`|`

, `^`

and `~`

are only defined
for `mpz_t`

. No conversion is performed. gmpc will abort
with an error message in case of a type mismatch.

gmpc
recognises constants that are accepted by the underlying GMP
functions `mpX_set_str()`

with a `base`

argument of `0`

.

For `mpq_t`

and `mpz_t`

, decimal constants
are accepted. Furthermore, gmpc handles prefixes for hex
(`0x`

or `0X`

), octal (`0`

) and
binary (`0b`

or `0B`

).

For `mpf_t`

only decimal constants are accepted.

For more exotic bases, the following syntax can be used:

/* add a base 36 constant */ %% mpz_t x2 = x1 + (mpz_t) const ("ag12", 36);

The string and base arguments are passed directly to
`mpX_set_str()`

. The type is derived from a preceding
cast if present, otherwise the default type is used (so in the
previous example, the cast is not really needed). Note that this is
the only way to introduce `mpf_t`

or `double`

constants in an `mpq_t`

or `mpz_t`

body.

GMPS supports GMP function calls. Use
`gmpc -fdump-prototypes`

to see the complete list of
supported functions. This list should contain all functions that
can be called using the types that GMPS supports:
`mpq_t`

, `mpz_t`

, `mpf_t`

,
`double`

, `unsigned long int`

, ```
long
int
```

and `int`

(`void`

return values
are treated specially). This excludes functions like ```
void
mpz_random (mpz_t rop, mp_size_t max_size)
```

, because GMPS
does not know how to handle the `mp_size_t`

parameter.

GMP functions without a return value behave as if they do have a
return value. The `void`

return value is replaced with
the first parameter. This makes them easier to use in
expressions.

r_new = mpf_sqrt(r, x*x + y*y) + r_old;

Here, the square root is stored in `r`

and also used
in the addition.

Furthermore, it is allowed to omit the first parameter
altogether, if it is pass-by-reference. GMPS implicitly assumes it
is an output variable. So in the previous example, if
`r`

is not needed, the following would be
equivalent:

r_new = mpf_sqrt(x*x + y*y) + r_old;

GMPS does not treat arrays specially. Variable references may have trailing array index expressions. They are simply copied to the output file.

In this example, it is assumed that the arrays `A`

,
`B`

and `C`

have been set up beforehand. The
`[i]`

subscripts will be copied verbatim to the
output.

%% import mpq_t A, B, C; for (i=0; i<N; i++) { %% mpq_t %% A[i] = f * B[i] + (1-f) * C[i]; }

Arrays must be imported, and since gmpc does not know anything
about array dimensions, they must be imported as scalars. In GMPS,
`A[1]`

and `A[1][i+j]`

have the same type as
`A`

.

**Note**: GMPS does not support nested
`[]`

brackets, so things like `A[c[i,j]][k]`

will be rejected by gmpc.

In GMPS the operator precedence is the
same as in C. This means that in many cases the evaluation order is
predictable, at least to a degree that makes sense mathematically.
So `a+b*c`

is equivalent to `a+(b*c)`

, or
maybe `(c*b)+a`

but never `(a+b)*c`

.
Especially if `a`

, `b`

and `c`

have different types, they may be shuffled around to better fit the
available GMP functions.

Increment and decrement operations are treated as side effects, which are guaranteed to have been fully evaluated at certain points in an expression. In GMPS these points are:

- At the end of a full expression, i.e. at the semicolon or closing brace.
- Directly before a function call, after the arguments have been evaluated.
- Between the evaluation of the left and right operands of the
boolean operators
`&&`

and`||`

.

This is essentially the subset of C sequence points that are relevant to GMPS.

This
section shows an annotated example of a sine function. The source
file, `sine.gmpc`, can be
found in the `tests`

directory of the gmpc
distribution.

First, the usual `#include`

statements are
needed.

#include <stdio.h> #include <gmp.h> %% static declarations;

We want gmpc to create static declarations, directly after the
`#include`

statements, and before the definition of the
`mpf_sine_raw`

function.

/* raw sine, first quadrant only, using Taylor */ void mpf_sine_raw(mpf_t sum, mpf_t x) { %% import mpf_t sum, x;

The function parameters must be imported, since we do not want
gmpc to create `init`

and `cleanup`

code for
them.

long int n_narrowing = 3; long int i; long int i_fact = 1; long int sign = 1; %% import long int i_fact, sign;

We will manipulate these variables in C, so we define them in C and then import the variables that are used in the formulas into GMPS.

int stop = 0; %% import int stop; %% mpf_t abs_tol = x * 1e-50;

`stop`

should be a boolean with function scope, so we
declare it in our C source and then import it. `abs_tol`

is not defined, so gmpc will create it for us, with file scope.

/* divide angle by 5 a few times, undo later using */ /* sin(5*x) = 16*sin^5(x)-20*sin^3(x)+5*sin(x) */ for (i=0; i<n_narrowing; i++) { %% mpf_t { %% x *= 1/5; %% abs_tol *= 1/5; %% } } /* init Taylor, i = 1 */ %% mpf_t { %% sum = x; %% xi = x; %% x2 = x * x; %% }

We introduce some more undefined variables, which will be taken care of by gmpc.

/* Taylor series expansion, i = 3, 5, 7, ... */ for (i=3; !stop; i += 2) { sign *= -1; i_fact *= (i-1) * i; %% mpf_t { %% xi *= x2; %% term = sign * xi / i_fact; %% sum += term; %% stop = mpf_abs(term) < abs_tol; %% } } /* Blow up angle again */ for (i=0; i<n_narrowing; i++) { %% mpf_t { %% sum2 = sum * sum; %% sum *= 5 + sum2 * (-20 + 16 * sum2); %% } } }

We need a `main`

to test our function.

int main(void) { mpf_set_default_prec (100); %% init;

Initialisation code will be inserted here.

%% mpf_t { test_sine = 0; test_arg = 0.5; }

Again, let gmpc handle these variables.

gmp_printf("mpf_sine_raw(%.Ff) = ", test_arg); mpf_sine_raw(test_sine, test_arg); gmp_printf("%.Ff\n", test_sine); return 0; }

This completes `sine.gmpc`.
gmpc is invoked as follows:

gmpc -Wall -o sine.c sine.gmpc

After a lot of warnings, a file `sine.c` is produced.

sine.gmpc:18:14: warning: undefined variable 'abs_tol' sine.gmpc:34:12: warning: undefined variable 'xi' sine.gmpc:35:12: warning: undefined variable 'x2' sine.gmpc:45:16: warning: undefined variable 'term' sine.gmpc:55:16: warning: undefined variable 'sum2' sine.gmpc:65:16: warning: undefined variable 'test_sine' sine.gmpc:65:31: warning: undefined variable 'test_arg' sine.gmpc: warning: missing cleanup section

The resulting `sine.c` can
be compiled:

gcc -lgmp sine.c

And the result of all this is:

./a.out mpf_sine_raw(0.5) = 0.4794255386042030002732879352155713880842

For the sake of completeness, here is the generated
`sine.c`:

#line 1 "sine.gmpc" #include <stdio.h> #include <gmp.h> #line 6 "sine_example.c" static mpf_t abs_tol; static mpf_t gmpscf000; static mpf_t gmpscf001; static mpf_t gmpscf002; static mpf_t gmpscf003; static mpf_t gmpscf004; static mpf_t gmpscf005; static mpf_t gmpscf006; static mpf_t gmpstf000; static mpf_t sum2; static mpf_t term; static mpf_t test_arg; static mpf_t test_sine; static mpf_t x2; static mpf_t xi; #line 5 "sine.gmpc" /* raw sine, first quadrant only, using Taylor */ void mpf_sine_raw(mpf_t sum, mpf_t x) { long int n_narrowing = 3; long int i; long int i_fact = 1; long int sign = 1; int stop = 0; #line 33 "sine_example.c" mpf_mul (abs_tol, x, gmpscf000); #line 19 "sine.gmpc" /* divide angle by 5 a few times, undo later using */ /* sin(5*x) = 16*sin^5(x)-20*sin^3(x)+5*sin(x) */ for (i=0; i<n_narrowing; i++) { #line 41 "sine_example.c" mpf_mul (x, x, gmpscf001); mpf_mul (abs_tol, abs_tol, gmpscf001); #line 28 "sine.gmpc" } /* init Taylor, i = 1 */ #line 49 "sine_example.c" mpf_set (sum, x); mpf_set (xi, x); mpf_mul (x2, x, x); #line 37 "sine.gmpc" /* Taylor series expansion, i = 3, 5, 7, ... */ for (i=3; !stop; i += 2) { sign *= -1; i_fact *= (i-1) * i; #line 60 "sine_example.c" mpf_mul (xi, xi, x2); mpf_set_si (term, sign); mpf_mul (term, xi, term); mpf_set_si (gmpstf000, i_fact); mpf_div (term, term, gmpstf000); mpf_add (sum, sum, term); mpf_abs (gmpstf000, term); stop = mpf_cmp (gmpstf000, abs_tol); stop = ((stop) < (0)); #line 49 "sine.gmpc" } /* Blow up angle again */ for (i=0; i<n_narrowing; i++) { #line 76 "sine_example.c" mpf_mul (sum2, sum, sum); mpf_mul (gmpstf000, gmpscf002, sum2); mpf_add (gmpstf000, gmpscf003, gmpstf000); mpf_mul (gmpstf000, sum2, gmpstf000); mpf_add (gmpstf000, gmpscf004, gmpstf000); mpf_mul (sum, sum, gmpstf000); #line 58 "sine.gmpc" } } int main(void) { mpf_set_default_prec (100); #line 90 "sine_example.c" mpf_init (abs_tol); mpf_init (gmpscf000); mpf_set_str (gmpscf000, "0.1e-49", 10); mpf_init (gmpscf001); mpf_set_str (gmpscf001, "0.2e0", 10); mpf_init (gmpscf002); mpf_set_str (gmpscf002, "0.16e2", 10); mpf_init (gmpscf003); mpf_set_str (gmpscf003, "-0.2e2", 10); mpf_init (gmpscf004); mpf_set_str (gmpscf004, "0.5e1", 10); mpf_init (gmpscf005); mpf_set_str (gmpscf005, "0.e0", 10); mpf_init (gmpscf006); mpf_set_str (gmpscf006, "0.5e0", 10); mpf_init (gmpstf000); mpf_init (sum2); mpf_init (term); mpf_init (test_arg); mpf_init (test_sine); mpf_init (x2); mpf_init (xi); mpf_set (test_sine, gmpscf005); mpf_set (test_arg, gmpscf006); #line 66 "sine.gmpc" gmp_printf("mpf_sine_raw(%.Ff) = ", test_arg); mpf_sine_raw(test_sine, test_arg); gmp_printf("%.Ff\n", test_sine); return 0; }

Note how gmpc inserts `#line`

statements, so C
compilers and debuggers can refer directly to the
`.gmpc` file.

program: statement_list <<EOF>> | <<EOF>> ; statement_list: statement | statement_list statement ; statement: "init" ";" | decl_statement ";" | var_statement ";" | body_statement | "cleanup" ";" | {CSOURCE} ; decl_statement: "declarations" | "static" "declarations" ; var_statement: "import" any_type ident_list | "var" any_type ident_list ; ident_list: {IDENT} | ident_list "," {IDENT} ; body_statement: "body" any_type exp_arg | any_type exp_arg ; exp_arg: exp ";" | "{" exp_list "}" | "{" exp_list ";" "}" ; exp_list: exp | exp_list ";" exp ; arg_list: exp | arg_list "," exp ; exp: {OCTINT}|{FLOAT}|{HEXINT}|{BININT} | ident | exp "+" exp | exp "-" exp | exp "*" exp | exp "/" exp | exp "%" exp | exp "<<" exp | exp ">>" exp | exp "==" exp | exp "!=" exp | exp "<" exp | exp "<=" exp | exp ">" exp | exp ">=" exp | exp "&&" exp | exp "||" exp | exp "&" exp | exp "|" exp | exp "^" exp | "-" exp | "+" exp | "!" exp | "~" exp | "(" exp ")" | exp "=" exp | exp "<<="|">>="|[\-%+/*&^|~]"=" exp | "++" exp | "--" exp | exp "++" | exp "--" | {IDENT} "(" arg_list ")" | cast exp | const_escape ; cast: "(" any_type ")" ; any_type: long_int | "signed" | "signed" long_int | "unsigned" | "unsigned" long_int | "double" | "mpq_t" | "mpz_t" | "mpf_t" | "int" ; long_int: "long" | "long" "int" ; const_escape: "const" "(" \"[^"]*\" "," {OCTINT}|{FLOAT}|{HEXINT}|{BININT} ")" ; ident: {IDENT} | {IDENT} array_index_list ; array_index_list: "["[^]]*"]" | array_index_list "["[^]]*"]" ;

`-fbase`: Output base`-fdouble-format`: Double format`-fdump-prototypes`: Listing supported GMP functions`-ffloat-digits`: Float digits`-fno-linemarkers`: Suppressing linemarkers`-fprecision`: Precision`-fprefix`: Prefix`-help`: Help- -o, output file: Invoking gmpc
`-version`: Version number`-Wall`: Enabling all warnings`-Wmissing-sections`: Catching missing sections`-Wundefined-variables`: Catching undefined variables`-Wunused-expressions`: Catching unused expressions- Arrays: Arrays
- Body section: Body section
- Cleanup section: Cleanup section
- Command line options: Invoking gmpc
- Comments: Comments
- Constants: Constants
- Declarations section: Declarations section
- Double format: Double format
- Downloading: Downloading and installing
- Enabling all warnings: Enabling all warnings
- Evaluation order: Evaluation order
- Example: Complete example
- Float digits: Float digits
- Function calls: Function calls
- GMP prototypes, listing: Listing supported GMP functions
- GMPS expressions: GMPS expressions
- GMPS statements: GMPS
- Grammar: GMPS grammar
- Help, display: Help
- Import, keyword: Import
- Init section: Init section
- input file: Invoking gmpc
- Installing: Downloading and installing
- Introduction: Introduction
- Invoking gmpc: Invoking gmpc
- Missing sections, warning: Catching missing sections
- Output base: Output base
- Precedence: Evaluation order
- Precision: Precision
- Prefix: Prefix
- Suppressing linemarkers: Suppressing linemarkers
- Type, default: Default type
- Type, implicit conversion: Implicit type conversion
- Type, undefined variables: Type of undefined variables
- Undefined variables, warning: Catching undefined variables
- Unused expressions, warning: Catching unused expressions
- Var, keyword: Var
- Version number, querying: Version number