coding.html revision e1747e09e7cc6771dca1a1702e42e6401dbeebed
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyAn ANSI standard C compiler and library are assumed. Feel free to use any
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyANSI C feature.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyGiven a reasonable set of things to warn about (e.g. -W -Wall for gcc), the
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleygoal is to compile with no warnings.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyAll source files should have a copyright. The copyright year(s)
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyshould be kept current. The files and the copyright year(s) should be
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyUse tabs. Spaces are only allowed when needed to line up a continued
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyexpression. In the following example, spaces used for indentation are
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyindicated with "_":
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley printf("this is going to be %s very long %s statement\n",
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley _______"a", "printf");
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceVertical whitespace is also encouraged for improved code legibility by
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencegrouping closely related statements and then separating them with a
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencesingle empty line. There should not, however, be more than one empty
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceadjacent line anywhere.
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceLines should not be longer than 79 characters, even if it requires
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceviolating the indentation rules to do so. Since ANSI is assumed, the
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencebest way to deal with strings that extend past column 79 is to break
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencethem into two or more sections separated from each other by a newline
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceand indentation:
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence puts("This string got very far to the "
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence "left and wrapped. ANSI catenation "
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence "rules will turn this into one
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence "long string.");
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyComments should be used anytime they improve the readability of the code.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyComments may be single-line or multiline. A single-line comment should be
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyat the end of the line of there is other text on the line, and should start
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyin the same column as other nearby end-of-line comments. The comment
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyshould be at the same indentation level as the text it is referring to.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyMultiline comments should start with "/*" on a line by itself. Subsequent
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleylines should have " *" lined-up with the "*" above. The end of the comment
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyshould be " */" on a line by itself, again with the "*" lined-up with the
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyone above. Comments should start with a capital letter and end with a
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * Private variables.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley static int a /* Description of 'a'. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley static int b /* Description of 'b'. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley static char * c /* Description of 'c'. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyThe following lint and lint-like comments should be used where appropriate:
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* ARGSUSED */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* FALLTHROUGH */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* NOTREACHED */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* VARARGS */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley.h files should not rely on other files having been included. .h
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyfiles should prevent multiple inclusion. The OS is assumed to prevent
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleymultiple inclusion of its .h files.<P>
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence.h files that define modules should have a structure like the
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencefollowing. Note that <isc/lang.h> should be included by any public
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceheader file to get the ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencemacros used so the correct name-mangling happens for function
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencedeclarations when C++ programs include the file. <isc/lang.h> should
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencebe included for private header files or for public files that do not
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencedeclare any functions.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * Copyright (C) 1998 Internet Software Consortium.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * Permission to use, copy, modify, and distribute this software for any
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * purpose with or without fee is hereby granted, provided that the above
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * copyright notice and this permission notice appear in all copies.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley#ifndef ISC_WHATEVER_H
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley#define ISC_WHATEVER_H 1
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley ***** Module Info
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence * (Module name here.)
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence * (One line description here.)
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence * (Extended description and notes here.)
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence * (Information about multiprocessing considerations here, e.g. locking
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence * requirements.)
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * Reliability:
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence * (Any reliability concerns should be mentioned here.)
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * Resources:
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence * (A rough guide to how resources are used by this module.)
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence * (Any security issues are discussed here.)
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * Standards:
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence * (Any standards relevant to the module are listed here.)
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence/* #includes here. */
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence/* (Type definitions here.) */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley *** Functions
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceISC_LANG_BEGINDECLS
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence/* (Function declarations here, with full prototypes.) */
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceISC_LANG_ENDDECLS
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley#endif /* ISC_WHATEVER_H */
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceThe first file to be included in a C source file must be config.h.
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceThe config.h file must never be included by any public header file
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence(that is, any header file that will be installed by "make install").
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceTry to include only necessary files, not everything under the sun.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyOperating-system-specific files should not be included by most modules.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyInclude UNIX "sys" .h files before ordinary C includes.<P>
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceThere should be at most one statement per line. The comma operator
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceshould not be used to form compound statements.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if (i > 0) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley printf("yes\n"); i = 0; j = 0;
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence x = 4, y *= 2;
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyThe use of ANSI C function prototypes is required.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyThe return type of the function should be listed on a line by itself when
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyspecifying the implementation of the function. The opening curly brace should
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyoccur on the same line as the argument list, unless the argument list is
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleymore than one line long.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleystatic inline void
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* whatever */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyg(int i, /* other args here */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley int last_argument)
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley return (i * i);
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceCurly Braces do not get their own indentation.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyAn opening brace does not start a new line. The statements enclosed
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyby the braces should not be on the same line as the opening or closing
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleybrace. A closing brace should be the only thing on the line, unless
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyit's part of an else clause.<P>
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceGenerally speaking, when a control statement (<CODE>if, for</CODE> or
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence<CODE>while</CODE>) has only a single action associated with it, then no
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencebracing is used around the statement. Exceptions include when the
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencecompiler would complain about an ambiguous else clause, or when extra
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencebracing improves the readability (a judgement call biased toward not
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencehaving the braces).<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if (i > 0) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley printf("yes\n");
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley printf("no\n");
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyvoid f(int i)
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley printf("yes\n");
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence<LI>Do put a space between operators like '=', '+', '==', etc.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley<LI>Do put a space after ','.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley<LI>Do put a space after ';' in a 'for' statement.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley<LI>Do put a space after 'return', and also parenthesize the return value.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley<LI>Do not put a space between a variable or function name and '(' or '['.
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence<LI>Do not put a space after the "sizeof" operator name, and also
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceparenthesize its argument, as in <CODE>malloc(4 * sizeof(long))</CODE>.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley<LI>Do not put a space immediately after a '(' or immediately before a ')',
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyunless it improves readability. The same goes for '[' and ']'.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley<LI>Do not put a space before '++' or '--' when used in
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleypost-increment/decrement mode, or after them when used in
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley<LI>Do not put a space before ';' when terminating a statement or in a 'for'
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley<LI>Do not put a space after '*' when used to dereference a pointer, or on
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyeither side of '->'.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley<LI>Do not put a space after '~'.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley<LI>The '|' operator may either have a space on both sides or it may have no
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence<LI>Do not put a space after a cast.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyIf a function returns a value, it should be cast to (void) if you don't
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencecare what the value is, except for <CODE>printf</CODE><P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyAll error conditions must be handled.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyMixing of error status and valid results within a single type should be
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley os_descriptor_t s;
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley os_result_t result;
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley result = os_socket_create(AF_INET, SOCK_STREAM, 0, &s);
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if (result != OS_R_SUCCESS) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* Do something about the error. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * Obviously using interfaces like socket() (below) is allowed
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * since otherwise you couldn't call operating system routines; the
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley * point is not to write more interfaces like them.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley s = socket(AF_INET, SOCK_STREAM, 0);
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if (s < 0) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley</CODE></PRE>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyCareful thought should be given to whether an integral type should be
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleysigned or unsigned, and to whether a specific size is required. "int"
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyshould be used for generic variables (e.g. iteration counters, array
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleysubscripts). Other than for generic variables, if a negative value isn't
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleymeaningful, the variable should be unsigned. Assignments and
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleycomparisons between signed and unsigned integers should be avoided;
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleysuppressing the warnings with casts is not desireable.<P>
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceCasting should be avoided when possible. When it is necessary, there
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceshould be no space between the cast and what is being cast.<P>
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceBad (obviously for more than one reason ...):
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence (void) malloc(SMBUF);
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyA function should report success or failure, and do so accurately. It
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyshould never fail silently. Use of Design by Contract can help here.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyBit testing should be as follows:<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* Test if flag set. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if ((flags & FOO) != 0) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* Test if flag clear. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if ((flags & BAR) == 0) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* Test if both flags set. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if ((flags & (FOO|BAR)) == (FOO|BAR)) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* Test if flag set. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if (flags & FOO) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* Test if flag clear. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if (! (flags & BAR)) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyThe null pointer value should be referred to with "NULL", not with "0".
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyTesting to see whether a pointer is NULL should be explicit.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley char *c = NULL;
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if (c == NULL) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* Do something. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyWhen the data a pointer points to has been freed, or is otherwise no longer
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyvalid, the pointer should be set to NULL unless the pointer is part of a
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleystructure which is itself going to be freed immediately.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* text is initalized here. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley text = NULL;
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyExplicit testing against zero is required for numeric, non-boolean variables.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley if (i != 0) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* Do something. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* Do something. */
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceThe ?: operator should mostly be avoided. It is tolerated when
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencedeciding what value to pass as a parameter to a function, such as
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencefrequently happens with printf, and also when a simple (non-compound)
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencevalue is being used in assignment or as part of a calculation.
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceIn particular, using the ternary operator to specify a return value is
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence printf("%c is%s a number.\n", c, isdigit(c) ? "" " NOT");
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence if (gp.length + (go < 16384 ? 2 : 3) >= name->length) {
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence return (success ? ISC_R_SUCESS : ISC_R_FAILURE);
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceVariables should not have their values assigned or changed when being
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencepassed as parameters, except perhaps for the increment and decrement
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence malloc(size = 20);
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence fputc(c++, stdout);
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceAll public interfaces to functions, macros, typedefs, and
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencevariables provided by the library, should use names of the form
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence{library}_{module}_{what}, such as:
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence isc_buffer_t /* typedef */
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence dns_name_setbuffer(name, buffer) /* function */
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence ISC_LIST_HEAD(list) /* macro */
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence isc_commandline_argument /* variable */
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencehowever, structures which are typedef'd generally have the name of the
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencetypedef sans the final _t:
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence struct dns_rbtnode {
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrence /* ... members ... */
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceGenerally speaking macros are defined with all capital letters, but
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencethis is not universally consistent (eg, numerous isc_buffer_{foo}
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceThe {module} and {what} segments of the name do not have underscores
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceseparating natural word elements, as demonstrated in
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceisc_commandline_argument and dns_name_setbuffer above. The {module}
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencepart is usually the same as the basename of the source file, but
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencesometimes other {module} interfaces appear within one file, such as
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencedns_label_* interfaces in lib/dns/name.c. However, in the public
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencelibraries the file name must be the same as some module interface
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceprovided by the file; e.g., dns_rbt_* interfaces would not be declared
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencein a file named redblack.c (in lieu of any other dns_redblack_*
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceinterfaces in the file).<P>
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceThe one notable exception to this naming rule is the interfaces
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceprovided by <isc/util.h>. There's a large caveat associated with the
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencepublic description of this file that it is hazardous to use because it
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencepollutes the general namespace.<P>
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid LawrenceWhen a module provides an interface for internal use by other modules
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencein the library, it should use the same naming convention
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencedescribed for the public interfaces, except {library} and {module}
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceare separated by a double-underscore. This indicates that the name is
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrenceinternal, its API is not as formal as the public API, and thus it
e1747e09e7cc6771dca1a1702e42e6401dbeebedDavid Lawrencemight change without any sort of notice.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyWhen an object is allocated from the heap, all fields in the object must be
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyinitialized.<P>
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleySource which becomes obsolete should be removed, not just disabled with
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley#if 0 ... #endif.<P>