Uli's Web Site
[ Zathras.de - Uli's Web Site ]
Other Sites: Stories
Pix
Abi 2000
Stargate: Resurgence
Lost? Site Map!
 
 
     home | blog | moose | programming | articles >> blog

 Blog Topics
 
 Archive
 

15 Most Recent [RSS]

 Less work through Xcode and shell scripts
2011-12-16 @600
 
 iTunesCantComplain released
2011-10-28 @954
 
 Dennis Ritchie deceased
2011-10-13 @359
 
 Thank you, Steve.
2011-10-06 @374
 
 Cocoa Text System everywhere...
2011-03-27 @788
 
 Blog migration
2011-01-29 @520
 
 All you need to know about the Mac keyboard
2010-08-09 @488
 
 Review: Sherlock
2010-07-31 @978
 
 Playing with Objective C on Debian
2010-05-08 @456
 
 Fruit vs. Obst
2010-05-08 @439
 
 Mixed-language ambiguity
2010-04-15 @994
 
 Uli's 12:07 AM Law
2010-04-12 @881
 
 Uli's 1:24 AM Law
2010-04-12 @874
 
 Uli's 6:28 AM Law
2010-04-12 @869
 
 Uli's 3:57 PM Law
2010-04-12 @867
 

More...

Let's talk about Coding Style

Everyone has their own way of writing code. Their own conventions of where spaces go, how much something is indented, their own preference what color certain elements should be shown in on screen. As soon as you work in a team, be it as part of open source software or among colleagues in a company, you have to find common ground to ensure the code stays an understandable, coherent whole.

Here I'll present a few conventions I usually go by, plus my reasons for it. Most of it is based on hard, practical considerations, though a few are just personal preference.

Brackets in the same column

if( myVar )
{
// do something!
}
else
{
// do something else.
}

This is easily the most important formatting issue. People fight religious wars about whether to put the opening bracket on the same line as the "if" statement or method name, whether to put it at the same level as the "if" or indent it one tab deeper etc. I don't care at all about the actual indentation level too much (as long as inner is somehow deeper), but an opening and closing curly bracket have to be in the same horizontal column, so you can easily match them up with your eye.

While Xcode may have auto-indentation and may automatically insert brackets, I spend a lot of my time in SmartSVN, GitX or FileMerge, and these tools have very limited syntax coloring and no auto-indentation, and don't highlight blocks like Xcode's code collapsing feature does. While I do a merge, I need to be able to quickly see which brackets go together, so I can easily generate code that still compiles. Which is also why I prefer my curly brackets on their very own line: That way they're separate from the actual loop construct or conditional, and are more easily merged.

Xcode actually lets you customize its behavior in this case using the XCCodeSenseFormattingOptions user defaults dictionary in its preferences, and the BlockSeparator entry in it.

Consistent Uppercase/Lowercase

Aforementioned limited syntax coloring in all other tools I use daily also dictates the use of naming conventions: I like my macros ALL_UPPERCASE(). You can then easily tell the bits of code you need to be careful with (don't want a side effect to be executed twice because min(a,b) is actually a macro, not a function). The exception being macros like UKLog(), my variant of NSLog() that only gets compiled into debug builds. But that ends up being a function call (and is pretty much guaranteed to hand its stuff directly to NSLog()), so it's not a problem here.

Mind you, I don't care much about constants declared using #define. I try to use enum for constants where possible, because those are handled in the compiler, which produces much more predictable and less surprising results than the preprocessor because it actually knows the context it is in. Those and #defined simple, parameterless constants usually are camel-cased with a prefix, e.g. eMyEnumeratedConstant or kMyConstant. Or in Objective C code, I grudgingly tend to do as the Romans do and use the class-style prefix, UKIncrediblyUsefulNotification. Only preprocessor switches used in #if statements are all uppercase, because they may massively modify the code flow and have to stand out, like DEBUG or IS_LITE_VERSION or USE_FANCY_EXPERIMENTAL_FEATURE.

Consistent prefixes

While I'm talking about prefixes, a fairly new development is also that I've started to adopt C++-style mMemberVariable-prefix syntax for my Objective C instance variables. Now that @synthesize is there and supports different names, and Interface Builder understands IBOutlet @property..., this is actually feasible, and it's easier to distinguish member variables and local ones in code so you don't have dangling pointers from autoreleased objects. Before that, I used to prefix local variables with a lowercase "v", as in vItemIndex, or call them theItemIndex, just like parameters were called inMessage or outMessage and static variables get named sLookupTable.

The actual conventions used here aren't that important, but these have been used historically in various languages and frameworks I started out with, or on projects I've worked on. Some projects include external code that has different conventions. While ideally you'd have one convention throughout the entire code, as long as one tries to match the coding style of the surrounding code, one can at least maintain readability. And since you want to commit code back upstream in an open source project so the codebases don't diverge too much and you can take advantage of upstream bug-fixes, you'll sometimes just have to stick to their conventions.

Local variables get lined up

int         foo = 0,
bar = 0,
baz = 0;
int * ptrA = NULL,
* ptrB = NULL;
When I declare several local (including static) variables in a row, I usually line them up using tabs. That way, you have an easily scannable list of variable declarations in the current scope. Since code is written only once, but is read hundreds of times, and often you have to remind yourself what type that variable is declared as, I find it terrible to lump all variables together on one line.

Also, I don't really like the asterisk indicating a pointer type to be on the left. Well, I would like it, but sadly ptrB above would need a second asterisk without the int part, as the asterisk associates with the right-hand side. I know it helped simplify C's parser, but it's still terrible. But what am I complaining, it's too late now. I also feel kinda queasy about placing the asterisk right next to the variable name, because reading a line like *ptrB = NULL Just looks wrong. You don't assign NULL to an int! So I generally try to sort-of center it in the middle.

Correct use of NULL, nil, Nil, true, false, YES and NO

Sometimes I'm lazy, or in a hurry, and I don't look up what type a variable is at the top of a function. Usually, I do this when I can tell the type from the values that are assigned to the variable. If it's foo = true, foo is obviously a bool. If it's var = nil, var is necessarily an ObjC object. Correct use of constants makes reading and understanding code much faster. If I see someone assigning true in Objective C code, my "someone must be mixing ObjC and C++ here!" warning bells immediately go on. You wouldn't want all that noise and flashing lights just because you forgot to write YES.

Method parameters and their types go together

-(void)    showString: (NSString*)inMessage toUser: (UKUser*)desiredUser;

- (void)showString:(NSString *)inMessage toUser:(UKUser *)desiredUser;
My style of formatting methods (top) is also a little more spacious than Apple's default (bottom). The main reason is that I want to have each parameter and its type as a visually distinct element that can easily be spotted. Same goes for the return type. Again, this is fairly unimportant, but with limited or no syntax coloring in a helper tool, it suddenly becomes very helpful.

In headers, I also prefer the method names to start at the same horizontal column, so it's easier to scan for a method in a header. The method name is the most specific part of a method, and also serves as a quick user-readable explanation, so it should be easy to extract from a line. Like in UI design, brackets may function as separator lines, but make the design more busy and force the eye to distinguish them from other symbols. Whitespace only exists as empty space the eye has to jump over, and isn't ambiguous because it can't be a symbol. So adding a few spaces here makes all the difference in the world.

Brackets touch their identifier

if( condition == true )
DoSomething( kDoItQuickly, GetGlobalState() );
Conditionals, loops and function calls require their own special brackets around parameters. In this way, they are different from the optional brackets that one uses to control execution order in expressions. To express this distinction in my code, I don't put a space between a function name and its parameter list opening bracket. However, I do put a space after the opening bracket and before the closing bracket. This exposes the parameters a bit more explicitly, and also gives the first and last parameters a little breathing room, just like the space after the comma.

However, I don't do this if there are no parameters to be exposed, or for one-parameter function calls nested inside a more complex function call. That way, the one-parameter call becomes a single unit, and it is easier to distinguish each parameter of the surrounding function.

Again, this is one of my personal idiosyncrasies, but I find it helps readability.

You can make Xcode mostly support this in the XCCodeSenseFormattingOptions user defaults dictionary in its preferences, by adjusting theInExpressionSpacing, InFunctionArgsSpacing, PostColonSpacing, PreExpressionsSpacing and PreMethodTypeSpacing entries, however you'll get MyFunction( ) for parameterless function calls from auto-completion.

Syntax coloring

This is very much a personal preference, but Mac OS X has inherited the terrible Unix notion of using ugly shades of undefinable colors like brown, purple and pink. If you look at these colors in code, you see that they're generally only pretty when you look at them as numbers. They're colors I imagine a programmer would choose who doesn't care too much how they get displayed in the end.

I prefer using primary colors for the most important symbols (usually red comments, blue identifiers, green macros), plus slight brightness variations (light blue for project types, mid blue for language keywords, dark blue for Apple system types). I also use a mid grey for strings, so I immediately see my whole code as "disabled" if I forget to close a string. I usually start out with a modified version of the "Spartan" color scheme.

The advantage of these colors is that, when I show something on screen, I can actually communicate "the line to the left of the blue 'void'" or whatever. People who didn't major in arts generally look quite flummoxed when I tell them about a "reddish cobalt blue" or a "brownish purple".

Reader Comments: (RSS Feed)
ElGrowZone writes:
Almost the way I do :) Especially where to put the open curly bracket :) I also do the following: I only declare one variable 'per type and line' - no comma separated lists. And I prefer to not put a space between type and the 'pointer star *' since I prefer to see 'pointer to something' as a type (which I typedef eventually when cleaning up code). In this part, your style seems to be inconsistent (-> variable decl. vs. parameter decl.) to me. AND I curly bracket EVERY block, even a single line in an 'if/while/...' statement. Waste of space? Sure, but more readable AND secures future changes in my opinion! And I imagine you did your first 'serious' code in a language named after a man who invented a calculating machine back in the 1600-somethings :) [after hesitating some seconds, I submitted to the Moderator ...]
Patrick aka Jolly writes:
Somehow a lot of programmers I know use the brackets on a single line convention, even though I rarely see that in the wild. I'm a advocate for single line brackets as well - even though it does use more space. I also align the values in the variable settings. That stands out even more as settings. I would like to mention the use of: lowercase ALL non objects. camelCase anInstance. UpperCamel AClassName. and tests start with the constant not the variable. So it would be if( true == condition) ... in my code. This might look weird first, but you recognize the difference between a set and a comparison. Also comes in handy to prevent syntax errors that become semantic errors: e.g. if( result = NO ) vs. if( NO = result ) // both times I forgot an additional equal sign. And btw. it always - init { if( !(self=[super init]) ) { return nil; } as don't have to think about the open nil==self state for the whole method. Oh coding styles are so much fun - Patrick
StartupItems4ever writes:
o Member variables: Personally, I use '_' as a suffix or suffix. member variable -> foo_ private version -> _foo o Local variables: Some prefixes I use: tFoo -> the variable won't exist after the method returns. nFoo -> the variable is created in the method and will exist after the method returns. o Method parameters: Not a big fan of the parenthesis stuck to the parameter name. It makes names more difficult to read.
Stephen Celis writes:
You have an unusual style, but with reasonable justifications. A few notes, though: Aligning opening and closing brackets doesn't always translate well to other languages. You'll have gotchas in ECMAScript-based languages, for example, where bracketing is sometimes interpreted as an object literal. I also shy away from treating conditions and loops bracketing as functions, since "if", etc., are keywords, not functions, though I suppose this is really a matter of taste.
rg writes:
Why write if( true == condition) or if(condition == true) Why not just write if( condition ) that is so much clearer why the unnecessary == true . I see it a lot and it really bugs me.
Michelle writes:
Is there an easier way to make these changes? The command line method is prone to misspellings, bad syntax, etc. Also, is it necessary to reboot your computer to make them "take"? I made changes, closed and reopened XCode and there is no change. StartupItems4ever: I like the tFoo and nFoo notations. I also like foo_ for member variables, but I currently use _ for something else so I would need to make the switch at the start of a new project and stick with it.
Scott writes:
I found this article to be very helpful. I also like aligning my '{' vertically as my eye can quickly scan down to verify I've not forgotten to close a block as well as to immediately and clearly grasp the scope of any particular block. I've found this to be particularly helpful with nested blocks. Prior to reading this article I still hadn't fully made up my mind with regards to brackets touching their identifier. I really like the reasoning you put forth here and will use your style going forward I think. As far as color goes, I had read that midnight-style coloring causes less eye-strain long term. Any thoughts on that point? I think it's uglier by far, but I'm willing to make the sacrifice if there are legitimate health benefits for doing so. Also, I'm a big fan of multiple lines for methods that take multiple arguments. It not only breaks things up visually, but it also helps to clarify the relationships when you're nesting method calls. I realize this sometimes looks a bit like E.E. Cummings--as Wil Shipley would say, but that guy's code has almost no whitespace. Maybe I'm just a noob, but I find using whitespace as an aid for expressing the intention of the code to be completely invaluable for me. I guess that if I were smarter, or more experienced, I probably wouldn't need those extra cues, and therefore would find the extra space to be a wasteful annoyance. That's my theory at least. Any thoughts on multiple lines for multiple argument methods?
leeg writes:
I occasionally use the curly-brace-on-same-line style: if (foo) { when writing articles and the like, to waste less vertical space. But for writing code I've always used curly-brace-on-next-line.
StartupItems4ever writes:
@rg: "Why not just write if( condition ) that is so much clearer why the unnecessary == true ." Because when you use if (condition), you do not compare to true but to 0. It's also [a lot] less readable. Sure with == true, you have extra characters but everybody understand the test. Without == true, some people won't understand it. if (condition) -> Windows-like User Experience if (condition==true) -> Mac OS X like User Experience
Uli Kusterer replies:
Well, if( condition ) is really if( condition != false ) which is technically slightly different than if( condition == true ) if you're using a variable that doesn't only contain true or false (e.g. an int). It's not really a practical consideration in most cases. The main reason for writing the "== true" is readability. Though for me it depends. I often name my bool variables something like "lightIsOn" and then if( lightIsOn ) is actually very readable. So I think it's OK to use, and good style *if* your variable names form a decent sentence with the "if". Reversing the variable and the constant really only is important when you *need* the constant to compare to, e.g. in cases like if( 5 == myNumber ) because there it'll catch the typo.
Uli Kusterer replies:
Stephen, I don't really care about other languages here :-) Coding style is inherently language-dependent. Sometimes I make compromises because a project mixes languages and I would otherwise make mistakes switching between them. Sometimes languages are related or so similar that the same style works for all of them. But I wouldn't code C++ like I would ObjC or HyperTalk, so of course if a keyword has a different meaning in another language, my coding style has to be adjusted accordingly. I'm trying to be sensible here, not force my unavoidable domination over all other programmers' coding styles ;-)
Or E-Mail Uli privately.

 
Created: 2009-12-15 @315 Last change: 2024-11-15 @663 | Home | Admin | Edit
© Copyright 2003-2024 by M. Uli Kusterer, all rights reserved.