The Great Pointer Syntax Debate

Asterisk

In Objective-C and other C-based languages, pointers are declared using the asterisk character. So, to declare a pointer to a UIView object called foo, in most examples and documentation you will see:

UIView *foo;

Notice that the asterisk is placed directly next to the variable name. However, when performing a cast or when specifying a parameter type in a method, the syntax becomes:

-(void) addSubview:(UIView *)foo;

Notice that the asterisk is now grouped with the parameter’s type name. Why the inconsistency? A more consistent syntax for the first example would be:

UIView* foo;

This more clearly implies that foo is of type UIView pointer. The compiler doesn’t care either way because it ignores white space. But programmers love consistency. However, what about the following:

int* a, b, c;

This would seem to imply that a, b, and c are of all type int pointer. That is not the case. Only a is an int pointer, while b and c are of type int. That is because the compiler interprets the asterisk as belonging to the variable name to the right of it, not the type name to the left of it. So, to declare three int pointers in-line like this, the correct syntax would be:

int *a, *b, *c;

This is an argument for keeping the asterisk next to the variable name instead of the type name. So neither syntax seems ideal!

What makes it extra confusing is that the asterisk is also the dereference operator. The asterisk behaves differently when declaring pointers than when dereferencing pointers:

-(void) foo:(NSError**)error
{
  *error = [[NSError alloc] init];
}

Notice that we use two asterisks to declare a double pointer to an NSError object. But then inside the method we use a single asterisk to dereference it so it can be used normally (we “reduce the level of indirection”). Some programmers combine the meanings and use the asterisk’s dereferencing behavior to justify keeping the asterisk with the variable name in a pointer declaration, interpreting it as “dereferencing foo will return a UIView”:

UIView *foo;

Ultimately, whether to keep the asterisk next to the type name or the variable name when declaring a pointer is a matter of style and preference. In the words of Bjarne Stroustrup, creator of C++ (which is based on C just as Objective-C), “Whenever something can be done in two ways, someone will be confused. Whenever something is a matter of taste, discussions can drag on forever.”

However, Bjarne does throw in his two cents: “A typical C++ programmer writes int* p; and explains it p is a pointer to an int emphasizing type. Indeed the type of p is int*. I clearly prefer that emphasis and see it as important for using the more advanced parts of C++ well.”

OK, so if we keep the asterisk next to the type name, what about the issue with multiple pointer declarations on a single line? Bjarne simply says “Stick to one pointer per declaration and always initialize variables and the source of confusion disappears.”

Agreed.

About Martin Rybak

I am a New York area software developer and MBA with 10+ years of server-side experience on the Microsoft stack. I've also been a native iOS developer since before the days of ARC. I architect and develop full-stack web applications, iOS apps, database systems, and backend services.

4 responses to “The Great Pointer Syntax Debate

  1. It’s great to finally see someone outline the issues around this. The inconsistency has always annoyed me. It’s always interesting to see the language creators weigh in on “matters of taste”.

  2. Having the same freaking asterisk used both for declaring and de-referencing was my only big hurdle when learning about pointers. I don’t remember that it was ever explained clearly, so it was one of those aha moments when I finally figured it out.

  3. Nice post. I learn something totally new and challenging on sites I stumbleupon on a daily basis.
    It’s always exciting to read articles from other authors and
    use something from other sites.

Leave a reply to Nathan Hurst (@nahurst) Cancel reply