PARI/GP

Try GP in your browser
Main
  Download
  Packages
  Funding
  SEARCH

Help / Community
  FAQ
  Documentation
  Tutorials
  Mailing Lists
  Bugs
  Timeline
  Ateliers PARI/GP

Library
  Publications
  Contributed GP scripts
  Links
  Fun!

Development
  Latest Changes
  Version Control
  Coding Guidelines
  PariDroid
  Logo

Tests & benchmarks
  Buildlogs
  Coverage Report
  Doc Coverage
  Refcards test
  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. This will save everybody's time!

Best practices

  1. Language: write all comments in english. Keep function and variables names (in english) consistent and reasonably short. Only use 7bit characters.
  2. Patches: please use unified diffs to send patches to pari-dev, the BTS or the maintainers, as per diff -u. State 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, try make doc and make test-all: 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++/C99 one-line 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. Reusability: write short generic functions, with obvious functionality rather than huge monolithic ones. Avoid assumptions about the inputs, then document explicitly what is left, e.g. p must be prime.
  7. Memory allocation: 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/usersch[5-8].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 needs 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. Unreachable statements: if an unreachable statement must be included (for instance because the compiler does not know that pari_err cannot return), mark unreachable lines using a /*LCOV_EXCL_LINE*/ comment.
  3. GP2C: If you add or modify a function in the src/functions/ database, make sure the GP2C descriptions are up to date. Or state that you were unable to update them.
  4. Diagnostics: integrate them within the DEBUGLEVEL, DEBUGMEM scheme. Never use printf() directly, use wrappers like err_printf(). Use pari_warn() for warnings.
  5. Errors: use pari_err() for fatal errors, never exit() or abort(). Try to find an appropriate error type for pari_err(), then use the appropriate pari_err_XXX wrapper (leverages the compiler to check arguments). Avoid e_MISC (free form error messages) if possible: you lose in flexibility, but users can parse the error programmatically.
  6. The PARI stack: public functions should be gerepileupto-safe and, if possible, memory clean (not leave garbage on the stack). You may leave a few small objects on the stack to avoid a huge garbage collection, but this should be documented; stackdummy is often needed 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, 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: 2017-12-31 08:42:40
Copyleft © 2003-2022 the PARI group.