Coding conventions are always a favorite topic of argument among programmers, and I am no different in this respect. Therefore, I have laid out my thoughts on the matter, specifically relating to the C programming language, in the hopes that someone will find them useful (and also so that I can point at this page when someone speaks to the contrary). None of this is set in stone; anyone who sets an exact "standard" has probably not written enough code to understand why such restrictions on coding style are bound to fail. Therefore, these observations are more guidelines than laws. Some of these recommendations are "common sense", but one should not assume that such sense is as common as it might seem.
#define FOO_XYZ 123
#define FOO_ABCDEF 42
#define FOO_BLAH 31415
Using tabs here is a bad idea, since the number of tabs required on each line would depend on the size of a tab.#include<stdio.h>
int main(int argc,char**argv){
if (argc==1) printf("Hello, world!\n");
else printf("Hello, %s!\n",argv[1]);
return 0;
}
Write something like this:
#include <stdio.h>
int main(int argc, char **argv)
{
if (argc == 1)
printf("Hello, world!\n");
else
printf("Hello, %s!\n", argv[1]);
return 0;
}
Your code won't run any faster just because you squished the source file into half the size by reformatting it.// C++ comments in C programs; use /* C comments */. This is really just an extension of the
rule about extensions (pardon the pun) - C++ comments are not standard C(89), so avoid them unless you have a really
good reason (which you don't, because normal C comments are perfectly good at commenting things). C++ comments can be especially
dangerous in multi-line preprocessor macros:
#define XYZ(a) \
// frob 'a' \
frobnicate(a)
p = realloc(p, size); - this is a memory leak. Assign the return value of realloc() to a
temporary pointer and check if it's NULL first, in which case you still need to free() the original block of memory.
Otherwise, copy the temporary pointer back to the original.x & 3 == 1 is the same as
x & (3 == 1), not (x & 3) == 1. Also, always surround preprocessor macro parameters
with parentheses wherever they are used in the macro's definition.
Remember that the preprocessor only does text substitution, so complex expressions used as macro parameters will break things
unless parentheses are used.lint-like program as well.* next to the identifier, not the type:
int *x; /* good */
int* x; /* bad */
int *x, *y, *z; /* declares three int pointers (good) */
int* x, y, z; /* declares one int pointer and two ints (bad) */
Also remember that typedefs are smarter than plain text substitution:
typedef int *intptr;
intptr x, y, z; /* declares three int pointers (good) */
#define intptr int *
intptr x, y, z; /* declares one int pointer and two ints (bad) */
(x / 2), not (x >> 1).
Let the compiler pick the best way to perform the operation by telling it what you want it to do.