Bad Coding styles
I'm mostly a developer which spends lot of time in front of code, and this makes you quite sensible when reading code. So, I'm going to enumerate some of the things I usually see (mostly on windows-like software) which is considered incorrect or inapropiate (to be politically correct).
Don't depend on IDEs
IDEs are evil, there's no decent IDE with any powerful editor inside by default. And it's far more than known that notepad-like editors are not efficient or good for programming. There's no ultra portable-full featured-lightweight one. So, for some tasks you will have to work without it. Try to not depend on these tools. IDEs usually links you to use certain tools and prepares an specific build system that will be unusable outside its product. Do not depend on WIMP.
The only good points for using an IDE is the code autocompletion which is unnecessary for well designed software and code browsing that can be replaced by commandline utilities like ctags.
Do not write long sources
Avoid files with more than N lines (N should be defined at any time O:)
Fit your code in 80 columns
Windows programmers usually say that their source can be wrapped to 130 columns or more because current hardware have wider screens... That's to blame. This way you are discriminating the commandline people and of course, your source will be less readable because human reading is mostly done up/down than left/right.
The C compiler understand some basic types like char, int, etc.. If you want to make it more compiler-independent define some 'short length' types to avoid you to write long stuff like 'unsigned long long'. Use 'u64' for example. Remember that this is a type and not a constant, so if you are using a define, don't do it in uppercase! and remember that is better to use 'typedef'. If you are using a C99 compiler you can use 'stdint.h' to solve this problem.
Don't abuse stack frames
The use of nested frames in functions to isolate variables or code is ugly to read and makes the compiler do more useless work. Humans are here to make the computer's life easier.
Use pointer tables
Instead of massive switch/casing for calling optional functions.
Don't abuse type definitions
Is nice to read some piece of code with smarter basic type names, but it will be a bit anoying to slurp code from some place and use it in another program using another kind of syntax. This reduces portability and reusability.
Don't fool pointers
Currently there are 32 an 64 bit machines. Dont store pointers on integers or shit like that.
Don't abuse parenthesis
There are some priority rules in algorithmic parsing that can help you to reduce parenthesis. Learn the evaluation order of the operations!
Avoid using variables with long names. Variables are here to change. So you'll have to use them more than once probably. Try to find short and logical names for them. Avoid using single character variables unless they are for looping, counting or pointing.
Using SingleLine comments to comment >1 lines of code
Yeah, that's very common, and that's something i can only understand if you want to give some minor ascii-art look to your code. Use #if0/#endif to comment code or /* */ for human-related messages.
There's some people that tends to abuse on the newline which is very common outside the perl world. But please, dont abuse them, your source code is not a poem or a toilet paper. As shorter it is, as cleaner it is.
Use tabs or fixed spaces to indent your code to let the programmer's editor do it properly. But never use more than 4 spaces for indenting.
Enumerating with defines
There's a very powerful feature (which exists from inmemorial times) of C, C++ and other high level languages that allows you to define a type as enumeration and create series of values.
There's some people that prefers to spend more time aligning text and manually enumerating constants in this way.
Why the hell people tries to nest functions inside functions? isnt enought painful to use the 'inline' attribute? Both are bad designs of the current C compilers. DONT USE THEM.
Divide and conquer
Do not do everything in a single file or in a single function unless you have a good reason for this. Functions should never require more than two page scrolling and try to define senseful names on the files to describe its contents. Prefixing function names with file name usually helps the development without IDEs.
Reading code in uppercase is like being shouted and blamed by somebody all the time. It's anoying and makes me remember on BASIC, COBOL and other dead languages. Everytime you define something in uppercase outside the preprocessor god kills a cat.
Some people tend to make an extensible use of the compiler-specific attributes for making 'cool' and 'ugly' things like inlining assembly, making naked functions and stuff like that. These kind of things are not portable, and links your program to an specific compiler. Please MS and GNU people, don't hurt our minds.
Don't abuse the preprocessor
If you want to make your code modular, or enable some parts at compile time you can use the preprocessor. But if your code needs to be dupped because an #if, you will probably need to refactor your code and use macros or compile-time decision to get one or another file.
Don't use 99 languages
Reducing the number of languages used in your project to 2 or 3 will help the software maintainance and portability. Avoid abusing .NET 'features' like mixing VBasic with C++ and delphy.
c99 stack frames
The C99 standard allows you to do some shitty things like defining variables in the middle of the function or stuff like that. This makes the compilation process a bit harder and the resulting code will be longer because it will be growing/reducing the stack frame twice or more. Local variables should be always defined at the top of the function. It makes it more clean, readable and easy to understand. If your code is hard to understand because they are defined off-screen..you will probably need to think on refactoring
Static is your friend
The 'static' attribute for functions in C is to avoid these ones be visible outside the object, when you run your program, the linker has nothing to do with anything else out of main and the inter-object related symbols. static-ize the rest and make the linker/loader happier. It will probably help you to clean code because the compiler notifies you that there's no references to it. f.ex
Debuggers are not for coding
I met some people that can't live without a debugger embedded on it's favorite IDE. They _NEED_ to put breakpoints on their source and visualize structures. I can understand that maybe there are some good source level debuggers, but they should be used for debugging serious problems. The developer should not depend on it.
Don't use multiline macros
When you are using macros or defines, the preprocessor will do it in a single line, because the preprocessor is a line-based application. So this means that if the compiler or the applications fails in a macro you will be unable to know where exactly if failing. So this makes the code not much maintainable and ugly to debug.
System specific calls
There's no need to use system-specific functions for most of the programs. Read and follow POSIX which is a standard and if something POSIX doesn't works on your operating system ping the provider for it. Standards are here to stay. So don't use sprintf_s, t_main, stdafx and so
Package on top of a root directory
This is mostly related to software packaging than development. But you'll have to remember that if you package a source code inside a zip or tarball, make everything live inside a root directory with the same name of the compressed file. It's _VERY_ anoying to have to manually create them and makes the software packaging a bit more complex.
7 bits per byte are enought for writing your applications. If you need localized strings or utf characters use libintl or libnsl on external files parsed by the main program.
Don't use locales
English is (sadly?) the wordwide language used in computer science. Never write comments or program messages in localized languages. There are libraries for handling this, and all of them are in english.
Comments are for humans
And humans usually read code and not comments. If your code needs to be commented, you'll probably need to refactor your source.
Huge programs are not better or do more things
If you want your program to do lot of things, try to divide the problem in multiple applications or modules and define a way to communicate between them. Huge software is slow to compile and unnecesarily complex. Keep it simple.
Include files are for signatures
Dont write executable code in the .h files. They are for definitions and signatures.
Dont include more than once
Use #ifndef _INCLUDE_FOO_H_ ; #define _INCLUDE_FOO_H_ to avoid including the same file twice.
Some languages like Java or c# bases their APIs in mixed upper/lowercase function names. Thats probably good for they, because is something that comes with the language by default, but on C is cleaner to do it with underline junctions like foo_bar().
Avoid Long Switch/case
It's cleaner to read a long switch/case list than an if/else one. But most of the long switch/cases can be reduced in a 3 lines loop using an array of structs. refactor!
Dont use labels
The use of labels can break some internal rules of the compiler structures and reduce the possibilities to optimize the code. It makes the code harder to read and maintain. The only reason for using gotos is to keep error checking clean to read and try to maintain a single return point on every function.
Multiple returns per function
It's common to use 'return' so many times in the same function. But you dont have to abuse them. Try to use them only to avoid long conditional cases that makes the code unreadable. It's better for the compiler to only keep a single return. But at machine level should be better to use multiple returns.
C plas plas
C++ is a bad language design. Gives too much freedom and weird ways to do the same thing to the developer, providing huge facilities for memory leaks. You'll not find c++ compilers everywhere and for most of the applications the use of C++ is not necessary.
Don't read this document
export EDITOR="pkill -9 emacs; vim"