PARI/GP

Main:
  PARI/GP?
  Download
  Packages
  Search

Support:
  FAQ
  Documentation
  Mailing Lists
  Links

Development:
  Version Control
  Coding Guidelines
  Latest Changes
  Bugs
  Buildlogs

Statistics:
  Benchmarks
  WWW Stats

Coding guidelines

In order to keep the PARI/GP code consistent, please use the following conventions when writing code that you intend to check into our repository or submit to the development mailing list.

Best practices

  1. Language: all comments should be written in english. Try to keep function and variables names (preferably in english) consistent and reasonably short. Only use 7bit characters.
  2. Patches: Always send context diffs to pari-dev, the BTS or the maintainers (preferably, use diff -u). State precisely what the object of a patch is and check that the patch contains no useless chunk, unrelated to the patch object. Try to break big patches in small independent units.
  3. Robustness: before sending a patch, always try make doc and make bench: nothing should be changed in the latter unless you have a very good reason for it (state it), and then the patch must include the updated output for the test. The code should compile with all C89, C99 and C++ compilers (in particular, do not use gcc or MSVC extensions, or C++-style comments // blah).
  4. Globals: avoid adding global variables, even static to a code module. When it is unavoidable (?), make sure whether you need the THREAD modifier: do all threads need a copy of this or is it safe to share it?
  5. Tests: write tests for new code in src/test; if you fix a bug, you may add a regression test to the relevant test. Try not to change the make bench subset: it is a common reference point.
  6. Write short generic functions, with obvious (and reusable) functionality rather than huge monolithic ones. Avoid assumptions about the inputs, then document explicitly what is left, e.g. p must be prime.
  7. Avoid using malloc() / free(), the PARI stack is at your disposal.
  8. Comment non-obvious code, document shortcomings (use FIXME markers in the code), document each non-trivial function: above the definition, and possibly in doc/usersch5.tex, doc/develop.tex or src/functions/.

Finalization / Cleanup

  1. Scopes and declarations: check that all variables have a sensible scope, ideally the smallest possible scope. Define temporary variable at the start of the block that need them. (Only declare variables at the beginning of a block.) A function must be either static, or declared in paridecl.h or paripriv.h. A function ending up in paridecl.h must be documented in one of the doc/ manuals.
  2. If you add or modify a function in the src/functions/ database, make sure the GP2C descriptions are up to date.
  3. Try to integrate diagnostics within the DEBUGLEVEL, DEBUGMEM scheme. Never use printf() directly, use wrappers like fprintferr(). Use the pari_err() and pari_warn() functions for fatal errors and warnings respectively, never exit() or abort().
  4. Public functions should be gerepileupto-safe and, if possible, memory clean (not leave garbage on the stack). It is allowed to leave a few small objects on the stack to avoid a huge garbage collection, but this should be documented, and one should use stackdummy in this case.

Formatting, spacing and indentation

The most important is to be consistent with neighbouring code, never reformat the latter so that it adapts to your style.
  1. Line length: no line should be longer than 80 characters unless absolutely necessary. Do not leave trailing whitespace.
  2. Indentation: use 2 spaces for each indentation levels. Do not use TABs but actual whitespace characters.
  3. Where to put spaces: do not put spaces before an opening parenthesis or bracket when calling functions or indexing. Use them around equal signs and after commas or semi-colons.
  4. Where to put braces: either of these is acceptable
      if (a) {                      if (a)
        code();                     {
        code();                       code();
      }                               code();
                                    }
    
    the first one being usually preferred. Avoid uneccessary open/close braces and line breaks: use
      if (a) code();
    
    rather than
      if (a) {
        code();
      }
    
  5. Nesting: to limit indentation levels, it is often advisable to use
      for (...) {
        if (!a) continue;
        ...
      }
    
    rather than
      for (...) {
        if (a)
        {
          ...
        }
      }
    
    Try not to use repeated tests against a boolean flag to get out of deeply nested constructions. Often, moving part of the loop code to a subroutine and using a simple return is the best solution.

PARI/GP Development
Last Modified: 2011-11-30 11:27:23
Copyleft © 2003-2011 the PARI group.