EPITA Coding Style Standard *************************** This document is intended to uniformize the coding styles of EPITA engineering students during their first term. Covered topics: * Naming conventions * Local layout (block level) * Global layout (source file level), including header files and file headers * Project layout, including `Makefile''s _The specifications in this document are to be known in detail by all students._ During the initial period, all submitted projects must comply *exactly* with the standard; any infringement causes the mark to be multiplied by 0. This standard is usually relaxed during the second period (starting in january), mainly because of the evolution of project requirements: the use of Automake leverage constraints over `Makefile''s, and the use of languages other than C imply their own, different, coding styles. However, this *does not* mean that introducing new tools or language requirements in project during the first period automatically relaxes the standard: this has to be negociated on a per-case basis with the assistants. _Note that this document is complementary to the official document, which is written in french and is available on the assistants web site._ How to read this document ************************* This documents adopts some conventions described in the following nodes. Vocabulary ========== This standard uses the words _MUST_, _MUST NOT_, _REQUIRED_, _SHALL_, _SHALL NOT_, _SHOULD_, _SHOULD NOT_, _RECOMMENDED_, _MAY_ and _OPTIONAL_ as described in RFC 2119. Here are some reminders from RFC 2119: "MUST" This word, or the terms _REQUIRED_ or _SHALL_, mean that the definition is an absolute requirement of the specification. "MUST NOT" This phrase, or the terms _PROHIBITED_ or _SHALL NOT_, mean that the definition is an absolute prohibition of the specification. "SHOULD" This word, or the adjective _RECOMMENDED_, mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understod and carefully weighted before choosing a different course. "SHOULD NOT" This phrase, or the phrase _NOT RECOMMENDED_, mean that there may exist valid reasons in particular circumstances when the particular behavior is acceptable or even useful, but the full implications should be understood and the case carefully weighed before implementing any behavior described with this label. "MAY" This word or the adjective _OPTIONAL_, mean that an item is truly optional. One may choose to include the item because a particular circumstance requires it or because it causes an interesting enhancement. An implementation which does not comply to an _OPTIONAL_ item _MUST_ be prepared to be transformed to comply at any time. Rationale - intention and extension =================================== Do not confuse the intention and extension of this document. The intention is to limit obfuscation abilities of certain students with prior C experience, and uniformize the coding style of all students, so that group work does not suffer from style incompatibilites. The extension, that is, the precision of each "rule", is there to explain how the automated standard verification tools operate. In brief, use your common sense and understand the intention, before complaining about the excessive limitations of the extension. Beware of examples ================== Examples of this standard are there for illustratory purposes _only_. When an example contradicts a specification, the specification is authoritative. Be warned. As a side-note, do not be tempted to "infer" specifications from the examples presented, or they might "magically" appear in new revisions. Correlation with the authoritative document =========================================== The authoritative document, called "norme" and written in french, only covers a subset of the mandatory items (denoted by _MUST_, _SHALL_, _REQUIRED_). Compliance to that document is checked thoroughly and strictly. This document is more general. It expresses rules of thumbs and guidelines for elegance in C writing. It was extensively checked for compliance with the authoritative "norme", and can therefore be used as a substitute. Naming conventions ****************** Names in programs must comply to several rules. They are described in the following nodes : General naming conventions ========================== - Entities (variables, functions, macros, types, files or directories) _SHOULD_ have explicit and/or mnemonic names. #define MAX_LINE_SIZE 1024 #define COMMENT_START_DELIMITER '#' #define MAX_FILE_NAME_LENGTH 2048 - Names _MAY_ be abbreviated, but only when it allows for shorter code without loss of meaning. - Names _SHOULD_ even be abbreviated when long standing programming practice allows so: Maximum ==> Max Minimum ==> Min Length ==> Len ... - Composite names _MUST_ be separated by underscores (`_'). - Names _MUST_ be expressed in english. - Names _SHOULD_ be expressed in correct english, i.e. without spelling mistakes. Name capitalization =================== - Variable names, C function names and file names _MUST_ be expressed using lower case letters, digits and underscores *only*. More precisely, entity names _MUST_ be matched by the following regular expression: [a-z][a-z.A-Z0-9] *Rationale*: for this regular expression: while this is a technical requirement for C code, it is not for filenames. Filenames with uncommon characters or digit prefixes are inelegant. - C macro names _MUST_ be entirely capitalized. - C macro arguments _MUST_ be capitalized: #define XFREE(Var) \ do \ { \ if (Var) \ free(Var); \ } \ while (0) Name prefixes ============= - When declaring types, type names _MUST_ be prefixed according to the group they belong to: structure names _MUST_ start with `s_', typedefs with `t_', union names with `u_', enumeration names with `e_'. Beware, the prefix is _not_ part of the identifier, thus "anonymous typedefs" of the form `typedef int t_;' are _PROHIBITED_. typedef unsigned char t_cmap[COLOR_WIDTH * NCOLORS]; typedef unsigned char t_pixel; struct s_picture { int width; int height; t_cmap cmap; t_pixel *picture; }; *Rationale*: for not using suffixes instead: identifiers ending with `_t' are reserved by POSIX (beside others). *Rationale*: for using prefixes: they are the first characters read while the eye is parsing, and allow to tag the identifier without need to read it entirely. - Structure and union names _MUST NOT_ be aliased using `typedef'. It is therefore not correct to defined shortcut names to structures and unions prefixed with `t_'. *Rationale*: `typedef' hides the compound nature of structures and unions. - Global variable identifiers (variables names in the global scope), when allowed/used, _MUST_ start with `gl_'. Preprocessor-level specifications ********************************* The global layout of files, and sections of code pertaining to the C preprocessor, including file inclusion and inclusion protection, must comply to specifications detailed in the following sections. File layout =========== - Lines _MUST NOT_ exceed 80 characters in width, including the trailing newline character. - The DOS CR+LF line terminator _MUST NOT_ be used. Hint: do not use DOS or Windows standard text editors. - All source and header files _MUST_ start with a file header, which _MUST_ specify the file name, the project name, an optional location, the author's name and login name, and the creation and last modification timestamps. - File headers _MUST_ comply to the following template: /* ** for in ** ** Made by ** Login ** ** Started on ** Last update */ Hint: this layout can be obtained at EPITA with `C-c C-h' in Emacs. - When instantiating the previous template, the `for ...' part _MUST NOT_ be omitted. Hint: if the `' field is irrelevant (i.e. the file is independent), fill it with "self". - In order to disable large amounts of code, you _SHOULD NOT_ use comments. Use `#if 0' and `#endif' instead. *Rationale*: C comments do not nest. - Delivered project sources _SHOULD NOT_ contain disabled code blocks. Preprocessor directives layout ============================== - The preprocessor directive mark (`#') _MUST_ appear on the first column. - Preprocessor directives following `#if' and `#ifdef' _MUST_ be indented by one character: #ifndef DEV_BSIZE # ifdef BSIZE # define DEV_BSIZE BSIZE # else /* !BSIZE */ # define DEV_BSIZE 4096 # endif /* !BSIZE */ #endif /* !DEV_BSIZE */ - As shown in the previous example, `#else' and `#endif' _MUST_ be followed by a comment describing the corresponding initial condition. - When a directive must span over multiple lines, escaped line breaks (`\'-newline) _MUST_ appear on the same column. For this purposes, tabulations _MUST_ be used. This is wrong: This is correct: #define XFREE(Var) \ #define XFREE(Var) \ do \ do \ { \ { \ if (Var) \ if (Var) \ free(Var); \ free(Var); \ } \ } \ while (0) while (0) Hint: use `C-\' and `C-u C-\', or `M-i' under Emacs. Macros and code sanity ====================== - C macro names _MUST_ be entirely capitalized (*note Name capitalization::). - As a general rule, preprocessor macro calls _SHOULD NOT_ break code structure. Further specification of this point is given below. - Macro call _SHOULD NOT_ appear where function calls wouldn't otherwise be appropriate. Technically speaking, macro calls _SHOULD_ _parse_ as function calls. This is bad style: This is more elegant: #define MY_CASE(Name) \ #define MY_CASE(Action) \ case d_ # Name: \ return go_to_ # Action(); return go_to_ # Name(); [...] [...] switch (direction) { switch (direction) case d_left: { MY_CASE(left); MY_CASE(left) break; MY_CASE(right) case d_right: default: MY_CASE(right); break; break; } default: break; } *Rationale*: macros should not allow for hidden syntactic "effects". The automated standard conformance tool operates over unprocessed input, and has no built-in preprocessor to "understand" macro effects. - The code inside a macro definition _MUST_ follow the specifications of the standard as a whole. Comment layout ============== - Comments _SHOULD_ be written in the english language. - Comments _SHOULD NOT_ contain spelling errors, whatever language they are written in. However, omitting comments is no substitute for poor spelling abilities. - There _SHOULD NOT_ be any single-line comment. *Rationale*: if the comment is short, then the code should have been self-explanatory in the first place. - The delimiters in multi-line comments _MUST_ appear on their own line. Intermediary lines are aligned with the delimiters, and start with `**': /* /* * Incorrect ** Correct */ */ /* Incorrect */ For additional specifications about comments, see *Note File layout:: and *Note Global specifications::. Header files and header inclusion ================================= - Header files _MUST_ be protected against multiple inclusion. The protection "key" _MUST_ be the name of the file, entirely capitalized, which punctuation replaced with underscores, and an additional underscore appended. For example, if the file name is `foo.h', the protection key _SHALL_ be `FOO_H_': #ifndef FOO_H_ # define FOO_H_ /* ** Contents of foo.h */ #endif /* !FOO_H_ */ - When including headers, *all* inclusion directives (`#include') _SHOULD_ appear at the start of the file. - Inclusion of system headers _SHOULD_ precede inclusion of local headers. This is bad style: This is elegant: #ifndef FOO_H_ #ifndef FOO_H_ # define FOO_H_ # define FOO_H_ int bar(); # include # include "bar.h" # include "bar.h" int bar(); int foo(); int foo(); # include #endif /* !FOO_H_ */ #endif /* !FOO_H_ */ Writing style ************* The following sections specify various aspects of what constitutes good programming behaviour at the language level. They cover various aspects of C constructs. Blocks ====== - All braces _MUST_ be on their own lines. This is wrong: This is correct: if (x == 3) { if (x == 3) x += 4; { } x += 4; } - Closing braces _MUST_ appear on the same column as the corresponding opening brace. - The text between two braces _MUST_ be indented by a fixed, homogeneous amount of whitespace. This amount _SHOULD_ be 2 or 4 spaces. - Opening braces _SHOULD_ appear on the same column as the text before. However, they _MAY_ be shifted with a fixed offset after control structures, in which case the closing brace _MUST_ be shifted with the same offset. These are wrong: These are correct: if (x == 3) if (x == 3) { { foo3(); foo3(); { { inner(); inner(); } } } } if (x == 3) if (x == 3) { { foo3(); foo3(); { { inner(); inner(); } } } } if (x == 3) { foo3(); { inner(); } } - In C functions, the declaration part _MUST_ be separated from statements with one blank line. Note that when there are no declarations, there _MUST NOT_ be any blank line within a block. An example is provided in the following section. Structures variables and declarations ===================================== Alignment --------- - Declared identifiers _MUST_ be aligned with the function name, using tabulations _only_. Hint: Emacs users, use `M-I'. The following is wrong: The following is correct: int foo() int foo() { { int i = 0; int i = 0; return i; } return i; } - In C, pointerness is not part of the type. Therefore, the pointer symbol (`*') in declarations _MUST_ appear next to the variable name, not next to the type. The following is incorrect The following is correct: (and probably does not have const char *str1; the intended meaning): const char *str2; const char* str1, str2; - Structure and union fields _MUST_ be aligned with the type name, using tabulations. - When declaring a structure or an union, there _MUST_ be only *one* field declaration per line. This is incorrect: This is correct: struct s_point struct s_point { { int x, y; int x; long color; int y; }; long color; }; - Enumeration values _SHOULD_ be capitalized or reasonably prefixed. *Rationale*: the use of common lowercase identifiers is discouraged because it clobbers the namespace. - Enumeration values _MUST_ appear on their own lines, properly aligned with the name of the enumeration. This is incorrect: This is correct: enum e_boolean enum e_boolean { true, false }; { b_true, b_false }; Declarations ------------ - There _MUST_ be only one declaration per line. - Inner declarations (i.e. at the start of inner blocks) are _RECOMMENDED_ when they can help improve compiler optimizations. - Declaration blocks in functions _SHOULD NOT_ contain `extern' declarations. - Variables _MAY_ be initialized at the point of declarations. However, for this purpose function and macro calls and composite expressions _MUST NOT_ be used. The following is wrong: int foo = strlen("bar"); char c = (str++, *str); This is correct: unsigned int *foo = &bar; unsigned int baz = 1; static int yay = -1; Hint: to detect uninitialized local variables, use the `-O -Wuninitialized' flags with GCC. Statements ========== - A single ligne _MUST NOT_ contain more than one statement. This is wrong: This is correct: x = 3; y = 4; x = 3; x = 3, y = 4; x = 4; - Commas _MUST NOT_ be used on a line to separate statements. - The comma _MUST_ be followed by a single space, _except_ when they separate arguments in function (or macro) calls and declarations and the argument list spans multiple lines: in such cases, there _MUST NOT_ be any trailing whitespace at the end of each line. - The semicolon _MUST_ be followed by a newline. - For a detailed review of exceptions to the three previous rules, *Note Control structures::. - Statements keywords _MUST_ be followed by a single whitespace, _except_ those without arguments. This especially implies that `return' without argument, like `continue' and `break', _MUST NOT_ be separated from the following semicolon by a whitespace. - When the `return' statement takes an argument, this argument _MUST NOT_ be enclosed in parenthesis. This is wrong: This is correct: return (0); return 0; - The `goto' statement _MUST NOT_ be used. Expressions =========== - All binary and ternary operators _MUST_ be padded on the left and right by one space, *including* assignment operators. - Prefix and suffix operators _MUST NOT_ be padded, neither on the left nor on the right. - When necessary, padding is done with a single whitespace. - The `.' and `->' operators _MUST NOT_ be padded, neither. This is wrong: This is correct: x+=10*++x; x += 10 * ++x; y=a?b:c; y = a ? b : c; - There _MUST NOT_ be any whitespace between the function and the opening parenthesis for arguments in function calls. - "Functional" keywords _MUST_ be followed by a whitespace, and their argument(s) _MUST_ be enclosed between parenthesis. Especially note that `sizeof' _is_ a keyword, while `exit' _is not_. This is wrong: This is correct: p1 = malloc (3 * sizeof(int)); p = malloc(3 * sizeof (int)); p2 = malloc(2 * sizeof char); - Expressions _MAY_ span over multiple lines. When a line break occurs within an expression, it _MUST_ appear just after a binary operator, in which case the binary operator _MUST NOT_ be padded on the right by a whitespace. Control structures ================== General rules ------------- - Control structure keywords _MUST_ be followed by a whitespace. This is wrong: This is correct: if(x == 3) if (x == 3) foo3(); foo3(); - The conditional parts of algorithmic constructs (`if', `while', `do', `for'), and the `else' keyword, _MUST_ be alone on their line. These constructs are These are correct: incorrect: while (*s) while (*s) write(1, s++, 1); write(1, s++, 1); if (x == 3) { if (x == 3) foo3(); { bar(); foo3(); } else { bar(); foo(); } baz(); else } { foo(); do { baz(); ++x; } } while (x < 10); do { ++x; } while (x < 10); `while' and `do ... while' -------------------------- - The `do ... while' construct _MAY_ be used, but appropriate use of the `while' and `for' constructs is preferred. `for' ----- Exceptions to other specifications (*Note Statements::, *note Structures variables and declarations::) can be found in this section. - Multiple statements _MAY_ appear in the initial and iteration part of the `for' structure. - For this effect, commas _MAY_ be used to separate statements. - Variables _MUST NOT_ be declared in the initial part of the `for' construct. This is wrong: This is correct: for (int i = 0, j = 1; int i; p = i + j, p < 10; ++i, ++j) for (i = 0, j = 1, p = i + j; { p < 10; /* ... */ ++i, ++j, p = i + j) } { /* ... */ } - As shown in the previous examples, the three parts of the `for' construct _MAY_ span over multiple lines. - Each of the three parts of the `for' construct _MAY_ be empty. Note that more often than not, the `while' construct better represents the loop resulting from a `for' with an empty initial part. These are wrong: This is correct: for (;;) ; for (; ; ) ; for ( ; ; ) ; Loops, general rules -------------------- - To emphasize the previous rules, single-line loops (`for' and `while') _MUST_ have their terminating semicolon on the following line. This is wrong: for (len = 0; *str; ++len, ++str); These are correct: for (len = 0; *str; ++len, ++str) ; *Rationale*: the semicolon at the end of the first line is a common source of hard-to-find bugs, such as: while (*str); ++str; Notice how the discreet semicolon introduces a bug. The `switch' construct ---------------------- - The `switch' _MUST_ be used *only* over enumeration types. - Incomplete `switch' constructs (that is, which do not cover all cases of an enumeration), _MUST_ contain a `default' case. - Non-empty `switch' condition blocks _SHALL NOT_ crossover. That is, all non-empty `case' blocks _MUST_ end with a `break', *including* the `default' block. This restriction is tampered by some particular uses of `return', as described below. - Control structure _MUST NOT_ span over several `case' blocks. This is very wrong: switch (c) { case c_x: while (something) { foo(); case c_y: bar(); } } - Each `case' conditional _MUST_ be indented from the associated `switch' once, and the code associated with the `case' conditional _MUST_ be indented from the `case'. This is wrong: switch (c) { case c_x: foo(); break; case c_y: bar(); break; default: break; } This is correct: This is also correct: switch (c) switch (c) { { case c_x: case c_x: foo(); foo(); break; break; case c_y: case c_y: bar(); bar(); break; break; default: default: break; break; } } - When a `case' block contains a `return' statement at the same level than the final `break', then all `case' blocks in the same `switch' (_including_ `default') _SHOULD_ end with `return', too. In this particular case, the `return' statement _MAY_ replace the `break' statement. This is inelegant: This is elegant: switch (direction) switch (direction) { { case d_left: case d_left: return go_to_left(); return go_to_left(); break; case d_right: case d_right: return go_to_right(); return go_to_right(); case d_down: case d_down: printf("Wrong\n"); printf("Wrong\n"); return do_it(); break; case d_up: default: return do_it(); break; } } return do_it(); *Rationale*: when using `switch' to choose between different return values, no condition branch should allowed to "fall off" without a value. - There _MUST NOT_ be any whitespace between a label and the following colon (":"), or between the `default' keyword and the following colon. Trailing whitespace =================== - There _MUST NOT_ be any whitespace at the end of a line. *Rationale*: although this whitespace is usually not visible, it clobbers source code with useless bytes. - There _SHOULD NOT_ be any empty lines at the end of a source file. Emacs users should be careful not to let Emacs add blank lines automatically. - When it is not a requirement, contiguous whitespace _SHOULD_ be merged with tabulation marks, assuming 8-space wide tabulations. - (Reminder, *note File layout::) The DOS CR+LF line terminator _MUST NOT_ be used. Hint: do not use DOS or Windows standard text editors. Global specifications ********************* Some general considerations about the C sources of a project are specified in the following sections. Casts ===== * As a general rule, C casts _MUST NOT_ be used. The only exception to this requirement is described below. *Rationale*: good programming behavior includes proper type handling. * For the purpose of so-called "genericity", explicit conversion between _compatible pointer types_ using casts _MAY_ be used, but _only_ with the explicit allowance from the assistants. "Compatible" pointer types are types accessible from one another in the subtyping or inheritance graph of the project. Hint: if you do not know what are subtyping nor inheritance, avoid using casts. Functions and prototyping ========================= - Any exported function _MUST_ be properly prototyped. - Prototypes for exported function _MUST_ appear in header files and _MUST NOT_ appear in source files. - The source file which defines an exported function _MUST_ include the header file containing its prototype. This layout is correct: File `my_string.h': #ifndef MY_STRING_H_ # define MY_STRING_H_ # include size_t my_strlen(const char *); char *my_strdup(const char *); #endif /* !MY_STRING_H_ */ File `my_strlen.c': File `my_strdup.c': #include "my_string.h" #include "my_string.h" size_t my_strlen(const char *s) char *my_strdup(const char *s) { { /* definition of my_strlen */ /* definition of my_strdup */ } } - Prototypes _MUST_ conform to the ANSI C standard: they must specify *both* the return type and the argument types. - Prototypes _SHOULD_ include argument names (in addition to their type). These are invalid prototypes: These are valid prototypes: foo(); int foo(int x); bar(int, long); void bar(int x, long y); int baz(); int baz(void); - Within a block of prototypes, function names _SHOULD_ be aligned. This is inelegant: unsigned int strlen(const char *); char *strdup(const char *); This is elegant: unsigned int strlen(const char *); char *strdup(const char *); - Function names in prototypes _SHOULD_ be aligned with other declarations. This is not recommended: int gl_counter; struct s_block *allocate(unsigned int size); void release(struct s_block *); This is recommended: int gl_counter; struct s_block *allocate(unsigned int size); void release(struct s_block *); - Function argument lists _MAY_ be broken between each argument, after the comma. When doing so, the arguments _MUST_ be properly aligned. This is correct: This is also correct: type foo(type1 p1, type2 p2); type bar(type1 p1, type2 p2, type3 p3); - Functions _MUST NOT_ take more than 4 arguments. *Rationale*: the C ABI on Unix specifies that the first 4 function arguments are always passed in registers, which yields more performance. In addition, if more arguments are needed, usually the modelling of the project is wrong. - An argument name _MAY_ be omitted at the point of _definition_ of a function, in the special case where it is not used by the function. *Rationale*: by omitting an argument name, the compiler warning saying that it is unused is inhibited. - Functions _SHOULD NOT_ return structures or unions by value. Structures or unions _SHOULD NOT_ be passed by value as function arguments, either. The use of dynamic memory management is encouraged instead. - Function arguments passed by reference _SHOULD_ be declared `const' unless actually modified by the function. Global scope and storage ======================== - There _MUST_ be at most *five* exported functions per source file. - There _SHOULD_ be only *one* non-function exported symbol per source file. *Rationale*: when statically linking executables against libraries, most linker algorithms operate with object file granularity, not symbol granularity. With only one exported symbol per source file, the link process has the finest granularity. Hint: track exported symbols with `nm'. - There _SHOULD NOT_ be any unused local (tagged with `static') functions in source files. Hint: hunt unused functions with `gcc -Wunused'. - In order to block known abuses of the previous rules, there _MUST NOT_ appear more than _ten_ functions (exported + local) per source file. - Static declarations are _NOT RECOMMENDED_. When required by a particular circumstance, there _MUST_ be *only one* static variable per line. - When initializing a static array or structure with const elements, the initializer value _MUST_ start on the line after the declaration: This is wrong: static int primes[] = { 2, 3, 5, 7, 11 }; These are correct: static const int primes[] = { 2, 3, 5, 7, 11 }; static const struct { char c; void (*handler)(void *); } handlers[] = { { 'h', &left_handler }, { 'j', &up_handler }, { 'k', &down_handler }, { 'l', &right_handler }, { '\0', 0 } }; Code density and documentation ============================== - (Reminder, *note File layout::) Lines _MUST NOT_ exceed 80 characters in width, including the trailing newline character. - Function definitions _SHOULD_ be preceded by a comment explaining the purpose of the function. This explanatory comment _SHOULD_ contain a description of the arguments, the error cases, the return value (if any) and the algorithm realized by the function. This is recommended: /* ** my_strlen: "strlen" equivalent ** str: the string ** return value: the number of characters ** my_strlen counts the number of characters in [str], not ** counting the final '\0' character. */ size_t my_strlen(const char *str); { /* definition of my_strlen */ } - Function bodies _MUST NOT_ contain comments. Any useful notice should appear before the function. - There _MUST NOT_ be any blank line elsewhere than between declarations and statements within a function body. - Function bodies _MUST NOT_ contain more than 25 lines, enclosing braces excluded. *Rationale*: function bodies should be kept short. - Many functions from the C library, as well as some system calls, return status values. Although special cases _MUST_ be handled, the handling code _MUST NOT_ clobber an algorithm. Therefore, special versions of the library or system calls, containing the error handlers, _SHOULD_ be introduced where appropriate. For example: void *xmalloc(size_t n) { void *p; p = malloc(n); if (p == 0) { fprintf(stderr, "Virtual memory exhausted.\n"); exit(1); } return p; } Project layout ************** Specifications in this chapter are to be altered (most often relaxed) by the assistants on a per-project basis. When in doubt, follow the standard. Directory structure =================== Each project sources _MUST_ be delivered in a directory, the name of which shall be announced in advance by the tutors. In addition to the usual source files, and without additional specification, it _SHOULD_ contain a number of additional files: `AUTHORS' This file _MUST_ contain the authors' names, one per line. Each line _MUST_ contain an asterisk, then a login name. The first name to appear is considered as the head of the project. *Rationale*: this file is to be `grep''ed over with a ^\* \([a-z-][a-z-]*_[a-z]\).*$ regexp pattern to extract login names. It is especially important to note that this specifications allows for _documenting_ a project by using actual text in the `AUTHORS' file: the regexp will only extract the relevant information. For example, consider the following text: This project was written with the help of: * foo_b (Foo Bar), main developer; * baz_y (Baz Yay), code consultant; * franco_l (Ludovic François), tutor Many thanks to them for their contribution to the project. Because the regex only matches the relevant information, it constitutes a valid `AUTHORS' file. `configure' When the project contract allows so, _and only then_, the script `configure' is automatically run before running the `make' command. It _MAY_ create or modify files in the current directory or subdirectories, but _MUST NOT_ expect to be run from a particular location. *Rationale*: allow for site configuration with Autoconf or similar tools. `Makefile*' Unless explicitely forbidden, the project directory _MAY_ contain an arbitrary number of files with names derived from "Makefile". These files are optional, although a `Makefile' _MUST_ be present at the time the command `make' is run. *Rationale*: the `Makefile' may include `Makefile-rules.make' or similar files for architecture-dependent compilation options. Makefiles and compilation rules =============================== - The input file for the `make' command _MUST_ be named `Makefile', with a capital "M". *Rationale*: although the latter name `makefile' is also valid, common usage prefer the former. - The `Makefile' (provided or generated by `configure') _SHOULD_ contain the `all', `clean' and `distclean' rules. - The `Makefile' _MUST NOT_ use non-standard syntax. In particular, it _MUST NOT_ expect to be parsed by GNU make ("`gmake'"). - The default rule _MUST_ be the `all' rule. - The `clean' rule _SHOULD_ clear object files, temporaries and automatic editor backups from the source tree. - The `distclean' rule _MUST_ depend on the `clean' rule, and _SHOULD_ clear executables, shared objects and library archives from the source tree. - The use of so-called "recursive `Makefile's" is discouraged; when used, the amount of redundancy between `Makefile's _SHOULD_ be kept low by proper use of `include' directives. - C sources _MUST_ compile without warnings when using strict compilers. The GNU C compiler, when provided with strict warning options, is considered a strict compiler for this purpose. Especially, when GCC is available as a standard compiler on a system, source code _MUST_ compile with GCC and the following options: -Wall -W -ansi -Werror Additionally, it _SHOULD_ compile without warnings with GCC and the following options (all documented in the GCC manual page): -Wall -W -ansi -pedantic -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Wunreachable-code - The previous requirement does _not_ imply that the `Makefile' must actually use these flags. It does _not_ imply that GCC must be always used: only the command `cc' is guaranteed to be available, and may point to a different compiler. - C compilation rules _SHOULD_ use the warning flag specifiers when possible. - `Makefile' rules _MUST NOT_ expect the presence of GCC on all target architectures. - As a side effect of the two previous rules, compiler differences and architecture-dependent flags _MUST_ be handled by appropriate use of the `uname' command. In particular, the environment variable `HOSTTYPE' _MUST NOT_ be used for this purpose, since it has a shell-dependant and architecture-dependent behaviour. Differences with previous versions ********************************** Differences with the legacy version =================================== The 2002 document was intended to supercede the legacy "norme", first written in (??), and last updated in October, 2000. It was based on the previous version, adding finer distinctions between requirements and recommendations, updating previous specifications and adding new ones. Here is a summary of the major changes: * Specification of the difference between "requirements" and "recommendations" was added. * Indentation requirements were clarified. * Header file specifications were clarified and updated to match modern conventions. * The `switch' construct is now allowed under special circumstances. * Prototyping specifications were clarified and detailed. * Naming conventions were clarified. * Declaration conventions were clarified and relaxed for some useful cases. * Line counting of function bodies was relaxed. The limit on the number of function arguments was explained and relaxed. * Comment specifications, including standard file headers, were clarified and detailed. * Project layout specifications were added. Default `Makefile' rules and rule behaviors were updated to match modern conventions. * Special specifications for C++ were added. In addition to these changes, the structure of the standard itself has been rearranged, and an index was added. Differences with year 2002 ========================== Starting with 2003, the assistants decided to revert to a short specification written in french, for readability convenience. The english document you are now reading is now a complement that can _optionnally_ used as a substitute. Here is a summary of the major changes: * Names are required to match a regular expression. * Preprocessor directives indentation between `#if' and `#endif' is now mandatory. * Header protection tags now have a `_' appended. * Multiple declarations per line are now forbidden, due to abuses during the past year. * Cumulated declaration and initialization is now explicitely authorized. * Local external declarations (`extern' in block scope) are now implicitely authorized. * Statement keywords without argument are not followed by a white space anymore. * `else if' cannot appear on a single line any more. * Single-line empty loops are now forbidden (the traling semicolon must appear on the following line). * Return-by-value of structures and unions is now implicitely authorized. * `typedef' of structures and unions is now disallowed. * Line count for function bodies is now absolute again (empty lines, `assert' calls and `switch' cases are counted). * Project recommendations now insist on the fact that GCC must not always be used and that the `configure' script is not always allowed. * Sample `Makefile' and `configure' scripts are not provided anymore. Index and Table of Contents *************************** #define <1>: See ``Macros and code sanity''. #define: See ``Preprocessor directives layout''. #if 0: See ``File layout''. #ifdef <1>: See ``Header files and header inclusion''. #ifdef: See ``Preprocessor directives layout''. .h files: See ``Header files and header inclusion''. abbreviations: See ``General naming conventions''. ABI: See ``Functions and prototyping''. alignment of functions names in a declaration block: See ``Functions and prototyping''. alignment, enumeration values: See ``Structures variables and declarations''. alignment, functions and declarations: See ``Structures variables and declarations''. alignment, pointer declarations: See ``Structures variables and declarations''. alignments, structure and union fields: See ``Structures variables and declarations''. all: See ``Makefiles and compilation rules''. ANSI C, for prototypes: See ``Functions and prototyping''. arguments, do not pass structures by value: See ``Functions and prototyping''. arguments, maximum number in functions: See ``Functions and prototyping''. AUTHORS: See ``Directory structure''. blank lines, forbidden in functions: See ``Code density and documentation''. blank lines, within blocks: See ``Blocks''. blocks: See ``Blocks''. braces: See ``Blocks''. break <1>: See ``Control structures''. break: See ``Statements''. capitalization <1>: See ``Macros and code sanity''. capitalization: See ``Name capitalization''. case: See ``Control structures''. casts, do not use: See ``Casts''. clean: See ``Makefiles and compilation rules''. commas: See ``Statements''. commas, within for: See ``Control structures''. comments, after #else and #endif: See ``Preprocessor directives layout''. comments, before functions only: See ``Code density and documentation''. comments, delimiters: See ``Comment layout''. comments, file header: See ``File layout''. comments, language: See ``Comment layout''. comments, layout: See ``Comment layout''. compilation flags: See ``Makefiles and compilation rules''. compilation rules: See ``Makefiles and compilation rules''. configure: See ``Directory structure''. const, function arguments: See ``Functions and prototyping''. continue: See ``Statements''. control structure keywords: See ``Control structures''. CR+LF <1>: See ``Trailing whitespace''. CR+LF: See ``File layout''. declarations with initialization: See ``Structures variables and declarations''. declarations, one per line: See ``Structures variables and declarations''. declarations, within blocks: See ``Blocks''. default: See ``Control structures''. delimiters, comments: See ``Comment layout''. directives, layout: See ``Preprocessor directives layout''. directives, line breaks: See ``Preprocessor directives layout''. directives, macros: See ``Macros and code sanity''. disabling code blocks: See ``File layout''. distclean: See ``Makefiles and compilation rules''. do: See ``Control structures''. do ... while: See ``Control structures''. e_: See ``Name prefixes''. else: See ``Control structures''. empty loop body: See ``Control structures''. empty statements, within for: See ``Control structures''. enum: See ``Structures variables and declarations''. enumerations, use within switch: See ``Control structures''. examples, warning: See ``Beware of examples''. exit: See ``Expressions''. exported functions: See ``Global scope and storage''. expressions, padding with spaces: See ``Expressions''. for: See ``Control structures''. for, empty body: See ``Control structures''. functions and globals, maximum number: See ``Global scope and storage''. functions, maximum number of arguments: See ``Functions and prototyping''. functions, no comments within body: See ``Code density and documentation''. functions, prototype over multiple lines: See ``Functions and prototyping''. functions, return type: See ``Functions and prototyping''. GCC, use for warnings: See ``Makefiles and compilation rules''. genericity: See ``Casts''. gl_: See ``Name prefixes''. global functions: See ``Global scope and storage''. globals, maximum number: See ``Global scope and storage''. gmake: See ``Makefiles and compilation rules''. goto: See ``Statements''. header files: See ``Header files and header inclusion''. headers, inclusion: See ``Header files and header inclusion''. headers, prototypes of exported functions: See ``Functions and prototyping''. heading comments: See ``File layout''. if: See ``Control structures''. initialization: See ``Structures variables and declarations''. inner declarations: See ``Structures variables and declarations''. keywords, followed by whitespace <1>: See ``Control structures''. keywords, followed by whitespace <2>: See ``Expressions''. keywords, followed by whitespace: See ``Statements''. layout, comments: See ``Comment layout''. layout, directives: See ``Preprocessor directives layout''. layout, files: See ``File layout''. line breaks in preprocessor directives: See ``Preprocessor directives layout''. line breaks, within arguments list: See ``Functions and prototyping''. line breaks, within for: See ``Control structures''. line count within function bodies: See ``Code density and documentation''. lines, maximum length: See ``File layout''. link granularity: See ``Global scope and storage''. macro calls: See ``Macros and code sanity''. macro names: See ``Name capitalization''. make: See ``Directory structure''. Makefile <1>: See ``Makefiles and compilation rules''. Makefile: See ``Directory structure''. makefile, do not use: See ``Makefiles and compilation rules''. MAY: See ``Vocabulary''. multiple declarations: See ``Structures variables and declarations''. multiple inclusion protection: See ``Header files and header inclusion''. MUST: See ``Vocabulary''. MUST NOT: See ``Vocabulary''. names: See ``Naming conventions''. names, abbreviations: See ``General naming conventions''. names, alignment of functions: See ``Functions and prototyping''. names, case of: See ``Name capitalization''. names, enumeration values: See ``Structures variables and declarations''. names, for arguments in prototypes: See ``Functions and prototyping''. names, global variables: See ``Name prefixes''. names, header protection key: See ``Header files and header inclusion''. names, macros: See ``Name capitalization''. names, prefixes: See ``Name prefixes''. naming conventions: See ``Naming conventions''. operators, padding: See ``Expressions''. OPTIONAL: See ``Vocabulary''. options, warning generation: See ``Makefiles and compilation rules''. pointerness, alignment of declarations: See ``Structures variables and declarations''. preprocessor macros: See ``Macros and code sanity''. preprocessor, directives: See ``Preprocessor directives layout''. prototypes, for exported functions: See ``Functions and prototyping''. prototypes, spanning over multiple lines: See ``Functions and prototyping''. Rationale <1>: See ``Makefiles and compilation rules''. Rationale <2>: See ``Directory structure''. Rationale <3>: See ``Code density and documentation''. Rationale <4>: See ``Global scope and storage''. Rationale <5>: See ``Functions and prototyping''. Rationale <6>: See ``Casts''. Rationale <7>: See ``Trailing whitespace''. Rationale <8>: See ``Control structures''. Rationale <9>: See ``Structures variables and declarations''. Rationale <10>: See ``Comment layout''. Rationale <11>: See ``Macros and code sanity''. Rationale <12>: See ``File layout''. Rationale <13>: See ``Name prefixes''. Rationale: See ``Name capitalization''. rationale, definition: See ``Rationale - intention and extension''. RECOMMENDED: See ``Vocabulary''. registers, passing arguments in -: See ``Functions and prototyping''. REQUIRED: See ``Vocabulary''. requirement: See ``Vocabulary''. return: See ``Statements''. return, replaces break within switch: See ``Control structures''. RFC 2119: See ``Vocabulary''. s_: See ``Name prefixes''. semicolons: See ``Statements''. SHALL: See ``Vocabulary''. SHOULD: See ``Vocabulary''. sizeof: See ``Expressions''. spaces, within expressions: See ``Expressions''. spelling mistakes <1>: See ``Comment layout''. spelling mistakes: See ``General naming conventions''. statement, multiple per line: See ``Statements''. statement, within for: See ``Control structures''. static: See ``Global scope and storage''. structures, do not use as function return values: See ``Functions and prototyping''. structures, field alignment: See ``Structures variables and declarations''. switch: See ``Control structures''. t_: See ``Name prefixes''. tabulations: See ``Trailing whitespace''. template comment for headers: See ``File layout''. trailing whitespace: See ``Trailing whitespace''. transtyping, do not use: See ``Casts''. u_: See ``Name prefixes''. unions, field alignment: See ``Structures variables and declarations''. unused functions cannot appear: See ``Global scope and storage''. variables, declaration within for: See ``Control structures''. variables, multiple per line: See ``Structures variables and declarations''. variables, number of static declarations per line: See ``Global scope and storage''. warnings: See ``Makefiles and compilation rules''. while: See ``Control structures''. while, empty body: See ``Control structures''. whitespace, at the end of a line: See ``Trailing whitespace''. Table of Contents ***************** EPITA Coding Style Standard How to read this document Vocabulary Rationale - intention and extension Beware of examples Correlation with the authoritative document Naming conventions General naming conventions Name capitalization Name prefixes Preprocessor-level specifications File layout Preprocessor directives layout Macros and code sanity Comment layout Header files and header inclusion Writing style Blocks Structures variables and declarations Alignment Declarations Statements Expressions Control structures General rules `while' and `do ... while' `for' Loops, general rules The `switch' construct Trailing whitespace Global specifications Casts Functions and prototyping Global scope and storage Code density and documentation Project layout Directory structure Makefiles and compilation rules Differences with previous versions Differences with the legacy version Differences with year 2002 Index and Table of Contents