Const-correctness is important!

As subsystems grow, it becomes increasingly reasonable to define many of your constant primitives (strings, ints, floats) in a series of shared files so that they can be reused, both for text-completion in your IDE and for better readability. But there are better and worse ways of doing code reuse, and in Objective-C I find that this is often glossed over.

I know I sure glossed over some of the relevant details in my classes on Ansi C89, and it was such a subtle point that my teachers never spent much time on it either:

What is the difference between each of the following?

int i1;
int *i2;
int const i3;
int const *i4;
int *const i5;
int const * const i6;

If you’re a basic C programmer, you certainly know that i1 is an integer and i2 is a pointer to an integer.
You probably also know that i3 is an immutable integer (meaning read-only) and i4 is a pointer to an immutable integer. And if you knew that, you might quickly remember that in C convention i2 (or i4) could actually be an array of integers (or immutable array of integers).

This is very common in C, with strings:

const char *c = "Hello world!\n";
const char[] c = "How you doing?\n";

As a student you learn to write const char almost without thinking about it. For generations–since time immemorial–the C compiler has been putting all of the compile-time strings into a read-only table as an optimization, thus the practice of writing something like const char * becomes second nature. (In fact, back in my day C89 didn’t even know what to do with a non-const char *. The results were undefined if you tried! C11 might be smarter now, but I doubt it.)

So what’s char const * const? Sure looks a bit weirder!

This is something they kind of glossed over in my classes so honestly I never gave it much thought, but understanding this is important if you intend to define a file full of “constants” that are used throughout your application.

By declaring int *const i5;, I create a read-only pointer to read-write memory. Which means the pointer will always point to the same location in memory, but the value at that location can change.

Declaring int const * const i6;, I create a read-only pointer to read-only memory. Once I set the data at i6, nobody going to change it out from under me for the rest of the application’s lifetime. Programmers who make sure their memory is always defined as properly mutable or immutable are aiming for something called const-correctness. Const-correctness is a good thing, even if it can be rather subtle.

Okay, so how does this relate to Objective-C? Well…

Have you ever written a constants file full of strings that looked like this?

static NSString *optionA = @"Option A";
static NSString *optionB = @"Option B";
// ... 1000 lines later ...

My team has. If so, then you’re just waiting for an unwise programmer to come along and mess your stuff up!

optionA = @"Option B"; // Why not? Nothing stopping me from doing it! 

You don’t want somebody to come in and blow away all your constants, do you? Yeah, me neither. You expect your constants stay, well… constant. Objective-C developers are very comfortable with the notion of using immutable NSStrings, but seem to forget that somebody can overwrite their lovely data when their pointers themselves are mutable.

Don’t open yourself up to this pitfall. Start defining your NSStrings with the *const modifier! Get Const-correct.

static NSString *const optionA = @"Option A";
static NSString *const optionB = @"Option B";

You’ll be glad you did.

Oh, but I strongly do not recommend this:

static NSString const * const string = @"DataType is 'const NSString *'";

If you try that, you’ll see that Xcode starts freaking out when you use your string, warning you that you might pass a read-only NSString to a method that isn’t expecting it. Of course, you know better. NSString is already immutable! But the compiler doesn’t know that and it wants you to cast your const NSString * to an NSString * every time you use it.

Don’t cast it, fix it. The compiler is warning you because you have a const-correctness violation!

Ok, that’s all. Happy coding.

Advertisements

Objective-C: Property Accessors vs. Dot Syntax

A coworker surprised me today with a really odd bit of code. I have reproduced the pertinent bit below.

@interface ViewController : UIViewController
@property (nonatomic, readonly, getter = isActive) BOOL active;
@end
@implementation ViewController
// ... Unimportant details...
- (void)viewDidAppear:(BOOL)animated {
    if (self.isActive) { // ... huh?

    }
}

At first glance there may not be anything odd about this to you. It’s pretty clear that isActive is the getter for the active property, and it compiles and runs just fine. But I suggested that he should write self.active instead of self.isActive. The only problem is that both ways–his and mine–work correctly. And so, I was struggling to explain why–in meaningful terms–he should change what he’s doing if there’s no obvious problem with how he’s using Objective-C’s Dot Syntax.

To do that, let’s review some basic Dot Syntax. Continue reading

Meta 2: Pasting Code In WordPress

Who knew blogging had such a learning curve?

Today I’m just trying to paste code in my blog and have it look like maybe something that a fellow programmer might attempt to read for any reason other than pity. Personally I can’t stand code that’s been formatted into a pretty, proportional-width font. It feels like trying to use Microsoft Word as your IDE.

Frankly I can’t imagine anything more terrifying. So to spare myself that embarrassment, let’s give it a shot by heading to the only post editor on the WordPress site that isn’t likely to leave us tearing our hair out in frustration.

Username [Hover] Blog Name [Hover] New Post

My first instinct was to invoke the “Kitchen Sink” (Yes it’s really called the Kitchen Sink) and use “Preformatted” line styles for my code, but that just won’t work.  In fact, it’s completely awful! Every newline becomes a new preformatted code block separated by a white margin. You can remove the white margins between lines by deleting the newlines and then adding them back in with the return key, because that makes a lot of goddamn sense, but there doesn’t appear to be any other easy way.

But wait, I notice another option: “Visual” and “Text”, on the top right of the post editing area. These two tabs aren’t present on the other, weaker “New Post” sections.

In “Text” the editor is all fixed-width and formatting tags are visible. Amazingly, there’s a code button!

@interface ViewController : UIViewController {
NSString *state;
}

Wow. That doesn’t look half bad.

WordPress might be usable after all…

Metablogging

OK, I’ve already tried to do two posts and both have been lost because of a terrible web-based editor on WordPress. So now I’m going to post about WordPress, because you can always metablog about blogging.

From the “New Post” header at the top of the WordPress site the editor seems to be wretched and lacking support for autosaved drafts, both things I despise. Same if you “Pop Out” the “New Post” window, though it looks like it might be slightly less wretched if only because it exists in its own floating window.

However, from the UserName [Hover] Blog [Hover] Add New link there appears to be more features and notably I see an “autosaving drafts” feature. Which is good because, you know, some people might not like to lose their work all the time.

Oh, WHY GOD WHY does Google Chrome think that it would be logical if the backspace key functioned as a Back Button when there are editable text fields all over the screen that I’ve like, you know…been typing in?

Terrible. Oh well, guess I finally have a need to use Safari. I think I have found out The Right Way to blog on WordPress.

Next time I will see if I can figure out how to post code in a WordPress blog.