#acl All:read = C Coding Style Guide = This document sets out the mandatory style for all submitted C code in first year CSE courses. <> == C Program Layout == In a C program file items must be arranged in the following sequence: 1. Header comment 1. #included files 1. #defines 1. local struct typedefs 1. local prototypes 1. global vars (not used in first year CSE courses) 1. main function (if present) 1. local functions In a C header (.h) file items must be arranged in the following sequence: 1. Header comment 1. #ifndef guard 1. #included files 1. #defines 1. struct typedefs 1. prototypes 1. (extern) global vars (not used in first year CSE courses) A header comment should include: {{{ // WikiName (or full name for offerings without a wiki), Student Login. // Tutorial class and tutor name // Date // What this file is for (one line summary). // Possible longer explanation }}} == Names == * all names to be meaningful * conventions: || '''what''' || '''convention''' || '''example''' || || functions ||<|2(> camel``Case, lowercase first letter, no spaces or _ || `isCookie (nextItem)` || || variables || `oldCookieCount = 7;` || || anonymous variables (eg some loop counters) || single lowercase letter || `i++;` || || new typedefed types || camel``Case, lowercase first letter unless abstract, uppercase first letter if ADT. || `typedef struct _position {`<
>` int x;`<
>` int y;`<
>`}` '''`position`'''`;` || || constants || UPPER_CASE, words joined with _ || `#define MAX_COOKIES 5` || == Layout == * Use spaces for indents, not tabs * Indent 3 spaces OR 4 spaces per level, but not a mix in any file * Describe block structures using indentation, do not rely on { } alone * MAY include one space before and/or after parentheses delimiting function parameter list * Use compact { } placement eg {{{ void eatCookie (int age) { printf ("Yummy"); } }}} * no lines over 72 characters, (clearly) reformat expressions and comments as required to fit this limit. * no space before commas in parameter lists, at least one space afterwards. == if, while == * always use { }, even for single statement blocks * place opening brace compactly (after condition rather than on following line), eg {{{ while (cookies == 0) { ....; } }}} * use compact braces around ''else'' eg {{{ if (cookies == 0) { ....; ....; } else { ....; } }}} * do not further indent chained ''else if'' and ''else'' statements eg {{{ if (cookies == 0) { ....; ....; } else if (cookies < 10) { ....; } else if (cookies < 50) { ....; } else { ....; ....; } }}} == Declarations == * Declare variables at the top of the function * Declare one per line if initialised. Only use comma separated lists of variables in a declaration when they are related instances (eg `int row, col;`) * In a block of related definitions vertically align the names, types, and initialisations * initialise variables close to where they are first used. * all structs and enums defined with typedefs * place prototypes for functions which are only used locally at head of file * place typedefs for types which are only used locally at head of file * prototypes and typedefs for functions and types which are used in multiple files are placed in a meaningfully named .h file, which is included in the file in which the function is defined and also in each file which uses the function or type * dont #include a .h file in another .h file == Functions == * put the return type on same line as function name * should be kept as short, and broken into sub-functions as required * each function should have a single clearly defined purpose, this purpose should be reflected in its name. == Executable Statements == * one per line, not `i=0; j=0;` * don't use = as an operator * not `i = j = 0` * not `if (x = 1)` * don't use comma operator == Function definitions == * use static for all non-interface functions in library modules * use prototypes for all functions (even those returning int) (this permits parameter type checking) * don't turn parameter type checking off in prototypes with (), use (void) instead * prototypes at the top of the file * main is to be the first function in the file, function ordering to be roughly top down * give (sensible) variable names in prototypes == Structs == * typedefs are used to refer to structs * write struct ''tags'' (eg "_entry" in "struct _entry" below) in lowercase, and generally use the same name for the tag and the typedef, preceded by an underscore. * tags may be used in typedefs and when other typdefs need to forward reference the struct eg in the examples below "struct _entry" and "struct _node" would not be used again in the program: {{{ typedef struct _entry { char *name; int listing; } entry; }}} {{{ typedef struct _node *Node; typedef struct _node { int value; Node next; } node; }}} == typedefs == * concrete type names start with lower case letter * abstract type names start with upper case letter == Comments == * students have freedom in use and layout of comments, clarity is the most important criteria * blocks of comments: /* */ style is discouraged. c99 style // at the start of each line is preferred. * tip: be wary of too many inline comments, consider replacing them with a single block header comment. == Compiler Options == * unless explicitly stated otherwise all code should be compiled with {{{ gcc -O -Wall -Werror }}} == Structured Programming == * all code must be structured (save exception handling using asserts). This means for example * no multiple returns from functions * no break * no goto * no return from inside a loop or if block == No shortcuts == * In assessment tasks you may not use any language features or commands which have not been explicitly covered in class * for fairness we want everyone to have the same set of tools available to solve assessment problems == C syntax discouraged == None of the following c features may be used in your own programs unless you are explicitly instructed otherwise. * ternary if operator `?:`, the comma operator, = as an operator (eg `if (x = 0) `) * break, continue * switch, case * global vars, static vars. (static function definitions WILL be used for namespace control) * register, extern (not to be used by students, will be given by teachers as demonstration cases) * `do { } while ()` (`while () { }` is used instead) * union, enum * tag based structs only used in the typedef of the struct, elsewhere they are referred to by the typedef name. * pointer arithmetic (e.g. pointer++), indexing from a pointer not an array (e.g. &pointer[1]) * pointers to functions (a crude form of higher order functions, students can wait till it is done properly in an oo language) * const == Security == * Submitted code may not contain system calls or file IO unless explicitly permitted. * Code with security vulnerabilities, such as potential buffer overflows, will be regarded as incorrect and heavily penalised. == Thanks == Parts of the initial version of this document was based on "Appendix C: C Programming Standards" of ''Programming Techniques using the language C'', Government of South Australia, Pearson Education Australia 2005. Subsequently it has been expanded and revised based on the experiences of using it in our courses. It has benefited from the suggestions and comments of numerous 1911, 1921, 1917, 1927 and 2911 teaching staff and tutors. Thank you to all who have contributed.