Coding style

From ASCEND
Jump to: navigation, search

ASCEND has had a large number of contributors over its history with the result that several different code styles are present in the core code and in the various GUI and solver code, etc. We are going to try to establish a few style guidelines here; if everyone can try to stick to these for new code in ASCEND then it will allow us to converge gradually to more uniformly readable code.

Unless you are permitted to work on our main 'trunk' line of code, please do not attempt to 'repair' existing code to meet the current guidelines; such repairs make it much more difficult to correctly merge code from developers working in parallel.

GPL headers

All code files should begin with a "GPL block" -- the format for C code is shown below. Copyright should by preference be assigned to Carnegie Mellon University, because that improves the chances of successfully fighting a license offender. Note that if you're not willing to place a GPL license at the top of code you are contributing to ASCEND, then we need to talk to you before you make your contribution. Maintaining a suitable open source license for our code is very important to the project. Exception: LGPL is also acceptable if the code is fully separable from existing GPL code.

/*	ASCEND modelling environment
	Copyright (C) 2011 Carnegie Mellon University

	This program is free software; you can redistribute it and/or modify

	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2, or (at your option)
	any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330,
	Boston, MA 02111-1307, USA.
*//** @file

	Implementation of non-GUI-specific parts of the Integration Interface.

	(this part is API documentation for use by a developer who is *using*
	but not *modifying* a module of code)

	(note, this @file block is only required in a ".h" file)

*//*
	by John Pye, DATE

	(add some more documentation here for developers who might be trying to
	change or improve this code, some stuff about how it works, why it was
	written the way it is, etc.
*/

/* now start with the real business... */

Conserve existing code

  • Never reformat existing code for any particular style; apply style rules below when creating new code.
  • Never replace existing tabs with spaces or existing spaces with tabs.
  • Never turn on or use autoformatting in an editor unless creating a new file.

Tabs

  • Please use tabs for indenting, not spaces.
  • We prefer a tab width of 4.
  • The only place that tabs should be present in your code is as part of the whitespace at the start of a line.
  • Do not use tabs to align comments after lists of variables etc; these break when people view the code with a different tab width.
  • It is a good practice to add "mode lines" at the start or end of files so that editors like vim, emacs, gedit and kate and others can automatically set the tab settings when code is loaded for editing, even if the coder's defaults are different.
  • Read this for a justification of why we like tabs and not spaces: http://www.movementarian.org/docs/whytabs/

C code conventions

  • Use plain ANSI C at all times.
  • You may use GCC features if you provide fallback code in ANSI C alongside (via #if...#else)
  • Avoid using one-line "if" statements; in general, any place that allows braces {}, please use them.
  • Avoid meaningless spaces between braces in "if", "while", "else". Spaces next to parenthesis and braces should only be added when really needed for readability.
  • With "if" statements, place the opening brace on the same line as the "if" (like K&R coding style), as follows:

if(condition){
    code;
}else{
    code;
}
  • Functions should be declared/formatted as follows, although note that the /** doxygen comment */ would preferably be placed in the .h file rather than the .c file, so that .h files become a useful reference resource.

/**
    do my stuff for me (summary of *what* it does)
    some doxygen syntax here:
    @param arg1 first argument
    @param arg2 second argument

    @return what the output is
*/
int my_function(double arg1, double arg2){

    /* explanations about how it works here */
    return 3;
}
  • Variable names should start lowercase
  • #defines should be ALL_IN_CAPITALS with a prefix that avoids potential global conflicts.
  • Structs should be declared as follows, within a typedef (note the resulting typedef is LeadingCapitalLetters):

typedef struct MyStruct_struct{
    int A;

    SomeOtherStruct B;
    double C;
} MyStruct;
  • Functions with related purpose should all bear a prefix to group them, in a sort of C-style object-orientation, and names should be all lower-case, as shown:

void mystruct_print(MyStruct *S);
int mystruct_count(MyStruct *S);

MyStruct *mystruct_new();
void mystruct_free(MyStruct *S);
  • Even when functions don't all apply to objects of the same type (eg MyStruct above) they should still bear a common prefix if they are a module of related functionality.
  • There are many examples of function names in the ASCEND code that do no conform to these conventions; we are migrating them gradually over time.

Global variables

Please, avoid the use of global variables at all times. We don't want any new global variables appearing; we're currently working to remove those that are there at present.

Comments in C/C++ code

  • C code should use /* this style */ of comments for all developer comments.
  • It is NOT acceptable to use "//" comments in C code to comment-out temporary #defines and so on; c89 does not allow compilation of these comments and we will continue to support c89 for a very long time.
  • Intermediate lines of comments should not not be started with a "*", i.e.

/* multi-line comment:
 * this kind is WRONG
 */

/*
    multi-line comment:
    this kind is RIGHT (these lines start with tab)
*/
  • Conservation rule: in many places (particularly the solvers), older styles are in use with multiple kinds of comment line prefix within the comment block. Reformatting these comments destroys information and should not be done.

API functions

Functions in libascend which will be accessed by 'user' code (GUI code, test suite code, etc) outside libascend should be prefixed in the relevant .h header file by ASC_DLLSPEC, which ensures that the relevant symbols are correctly exported to the shared library symbol list. This may not be necessary on your development system, but there are at least some systems where this is essential.

Doxygen

All API-exposed C functions should be provided with commenting that can be used by Doxygen. We use this program to generate our API documentation. There are plenty of good examples of how this is done, see the various header files in base/generic/system, for example.

Python code

Python code should contain tabs (not spaces) for indenting; please use a tab width of 4. Use modelines as noted above.

Currently, no automated documentation generators are being used with our Python code but we hope to change that soon. We will adopt conventions similar to those used by Gaphas.

C++ code

There is a moderate amount of C++ code in ASCEND as part of the Python API. This code helped to make the API easier to write, because of the ability to easily wrap STL data types using SWIG. We would ultimately like to clean out this C++ code, because it is bulky and slow to compile, and less efficient. Please consider this fact before plunging in to a lot of C++ coding. We would really like ASCEND to be pure C plus Python if possible.

Tcl/Tk code

The older (but still more mature and complete) GUI for ASCEND is written with a C-to-Tcl interface layer together with Tcl/Tk GUI code. We are not actively developing the Tcl/Tk GUI; if you see features in that GUI that are missing from the PyGTK you are encouraged to make a note of that and think about how such features could be migrated.

Compiler warnings

When building C and C++ code, please make sure that you are seeing '-Wall' flags (for GCC), to ensure that you're being warned about all possible faux pas that you may be making.

Assertions

For assertions in the C code, please use the assertion macros/functions defined in the header file <ascend/compiler/ascPanic.h>. Avoid making direct use of <assert.h> from the C Standard Library.

Memory allocation

For memory allocation in the C code, please use the macros ASC_NEW, ASC_NEW_ARRAY, ASC_NEW_CLEAR, ASC_NEW_ARRAY_CLEAR and ASC_FREE, defined in <ascend/utilities/ascMalloc.h>. Prefer these over alternatives like ascfree, ascmalloc and malloc. Using these macros universally will make use of various memory debugging tools a bit easier.

Filenames

Filenames in ASCEND should be all in lower-case. This ensures minimal problems between Windows (which is not case-sensitive) and Linux (which is case-sensitive).