C99 Initializer Syntax in Objective C

This week a colleague sent me a snippet of Objective-C syntax I had never seen before.

self.imageView.frame = (CGRect){.origin=CGPointMake(0.0f, 0.0f), .size=image.size};

This is (apparently) called C99 Initializer Syntax. This type of syntax can be used to initialize any struct in C (and Objective C) which is especially useful when working with CGRect and CGPoint.

The Syntax

Let’s take a look at the standard way of defining a CGRect.

CGRect frame = CGRectMake(60, 80, 200, 300);

I’ve never really thought about this, but the syntax only makes sense if you already know the order of the parameters and what they mean. This is not really an issue with CGRectMake – since you use this so often it’s impossible not to know the parameters – but it’s not ideal.

Take a look at the equivalent in C99 syntax.

CGRect frame = (CGRect){
    .origin.x = 60, 
    .origin.y = 80, 
    .size.width = 200, 
    .size.height = 300
};

This is much more readable and would be especially helpful if you were passing expressions instead of contants.

CGRect frame = (CGRect){
    .origin.x = (x / 2) + 60, 
    .origin.y = (y / 2) + 80,
    .size.width = x * 2, 
    .size.height = y * 2
};

What’s really nice about this syntax is that it’s not only more readable, it’s actually a bit safer. We can also write the following:

CGRect frame = (CGRect){
    .size.width = 200, 
    .size.height = 300,
    .origin.x = 60, 
    .origin.y = 80
};

We can also change the order of the parameters in the original struct without having to change this code. Obviously I’m not expecting the definition of CGRect to change, but it could be useful for your own structs or those of a library. (Remember that this syntax works for all structs)

The best usage of this syntax (in my opinion) is for when we want to specify the size or origin as a single value. For example, it’s not uncommon to do something like this:

CGRect frame = CGRectMake(
    self.view.frame.origin.x, 
    self.view.frame.origin.y, 
    200, 
    300
);

However, with the C99 syntax we can now write this:

CGRect frame = (CGRect){
    .origin = self.view.frame.origin, 
    .size.width = 200, 
    .size.height = 300
};

Which is definitely much more readable.

Default Values

Any parameters which are not specified will default to zero. So the following statements are actually equivalent.

CGPoint point = (CGPoint){.x = 0,.y = 0};
CGPoint point = (CGPoint){};

Using this syntax we can actually rewrite the original snippet I was looking at:

self.imageView.frame = (CGRect){.size=image.size};

Pretty neat.

Actual Usage

C99 Syntax can definitely be helpful in the right situation. Used correctly it can improve readability, used incorrectly it can make your code overly verbose.

Happy coding.