My coding style (for C++, at least) is probably slightly controversial. I use tabs, not spaces. Every brace, almost without exception, is on a new line (the exception is when the entire function definition, including braces, can be on one line).
Now one that is a bit weird, but I started doing for my own sanity awhile back: before every few lines, if not every line, there is a comment. After the line or set of lines, there is a blank line. It doesn’t matter if the comment says something extremely meaningful (though I prefer it to be meaningful), but it matters that it is there. The syntax coloring of the comment, combined with the line break, somehow makes the code much simpler for me to read.
It is preferable that the content be in first-person, but in plural form; that is, it is preferable that it start with “we,” as in “I and the program,” or “whoever you are reading this, and I the original programmer.” I don’t know why, but that is my preference, and, being the one who works most on the code, what I say goes.
Here is an example from a still very much work-in-progress function (so don’t make too much fun!) involved in the parsing of PDF:
PDFObject PDFFile::parse() { //there are a few main things we could see. We could see an object, or a //delimiter. //what we do is simple. Skip whitespace (we have a function for that), read //until either delimiter or whitespace. //we will either have a simple object (number, boolean, integer, null) //or a delimiter. The delimiter tells us what we may want to do next, for //instance, use parseString, parseName, etc. //NOTE: //peek is our friend. Since we read one character at a time, it is much more //practical than creating our own in-memory buffer to remember, for instance, //the last delimiter we saw. //consume whitespace this->consumeWhitespace(); //token buffer. This holds the token if we can process it whole. std::string buffer; //loop until we see either whitespace or a delimiter //(peeking the whole time) while (true) { char c = this->input->peek(); //if it is a delimiter or is whitespace, we are done reading. if (isWhitespace(c) || isDelimiter(c)) break; this->input->get(c); buffer += c; } //now parse our buffer. If it is empty, it must be a boolean, string, etc. if (buffer.length() == 0) { //we must have a delimiter. //see what it means. char delimiter; this->input->get(delimiter); //see what it is... if (delimiter == '(') { return processString(); //will consume up to the ending ) } else if (delimiter == '<') { //peek the next character. if it is also a <, then this is a dict. if (this->input->get( //note: this is why I said work-in-progress. // it isn't finished. } } }
Is the code a lot longer than it could be due to comments? Yes. But for one reason or another, it makes it much easier for me to understand and debug later.
Update: Something that, unfortunately, I am not consistent enough about is the use of the this-> prefix for variable and function names. I prefer to use it, but sometimes I don’t, as seen in “processString” above.