SW engineering, engineering management and the business of software

It sure would be nice if there was a code fairy flying over your shoulder that could sound a dulcet chime every time suspect code was introduced. Even better would be a swarm of fae to keep the entire project free of dubious practice. No such creatures seem to exist, but I will make the somewhat farcical claim that compiler warnings are a poor man’s army of code fairies and that enabling most all of them will eventually resolve into better apps. First, some backstory on how not to proceed.

-Wall is a lie!

The -Wall flag instructs the compiler to Enable All Warnings. However, gcc has an interesting definition of “All”, which is “Not All”. This is unfortunate as a codebase that compiles warning-free tends to behave better and have less uncovered edge cases.

The historical reason is that some warnings are intended to be more like notices where human judgement is required. The compiler is basically saying, “Watch out! Something questionable is happening here”.

Everyone’s definition of questionable is a bit different however, and there were some compiler warnings deemed as more informational than true exclamations of potential danger. Many of those warnings were excluded from -Wall, and as a compromise some of them were shoehorned into -Wpedantic and -Wextra.

After gcc usage became more and more widespread, it actually got harder to get new warnings included in the -Wall umbrella as this started to break toolchains. Once you get government standards bodies involved with the application of the -Wall flag, you more or less stop improving the -Wall flag.

Clang to the rescue

This brings us to Clang. Clang developers understand most of this history and decided that since -Wall and it’s ilk were mired in political and technical muck, they needed a new flag that is defined as “all current and future warnings forever”. They called it -Weverything which is pronounced “wevrything” and typically accompanied by large wavy outstretched arm gestures.

I’ll wait for that mental image to settle. Okay moving on.

But You Promised Better Apps!

This brings us to Better Apps.

Here’s a non-exhaustive, off-the-top-of-my-head list of edge cases and questionable behavior that -Wevertyhing can help diagnose:

non-existent selector warning

lossy integer conversion

enum usage in switch statements

memory leaks due to usage of self in blocks

preprocessor and pragma issues

slow builds due to not using modules

The list is roughly sorted in order of severity of potential problems. Stuff high on the list could cause runtime crashes and widespread decaffeination of coffee-stores around the world. Integer conversion edge cases in particular are a big source of crashes on 64bit iOS devices. Stuff towards the bottom simply wastes time & energy and likely induces hair loss.

-Weverything in Action

A small prototype project that I implemented in a few weeks that uses Core Data, some GCD, and some collection views and animations was my initial stab at -Weverything.

A clean build turned into a build with 307 warnings.

Many of these warnings are actually pretty nice and resolving them means my app is a little bit more resilient, a little bit more future-proof, and even builds a little faster.

Resolving them ended up only taking about 20 minutes or so, mostly thanks to Xcode under-appreciated Fix-It feature. The warnings spanned the range of important, nice, helpful, benign-but-I-just-want-the-warning-to-disappear stuff. At the end, I’m left with a handful of warnings I can’t or won’t fix.

At this point, we have to start disabling warnings. Because what -Weverything really means is “all current and future warnings forever, except those that I disable because of reasons”.

A Brief Interlude into Xcode

In Xcode, to enable -Weverything you need to go to the “Build Settings” pane. This can be done project-wide or only for specific targets. I tend to keep them strict for my app targets, then loosen them for test or tangential targets. The app gets a curfew, but the red-headed test targets can go out rutting like a drunken sailor for all I care.

The correct place to set -Weverything is in the “Other Warning Flags” line item.

If you wish to disable a certain warning, you first find out the warning flag’s root name then prepend -Wno- to it.

To get the warning flag’s root name in the issue navigator, right-click on a warning you’d like to disable, and select “Reveal in Log”. You should see something like this:

Weverything But The Girl

The objc-missing-property-synthesis is a no-brainer one to disable. This is one of those informative warnings; the compiler is telling you that it is auto-synthesizing the property. We love that the compiler does this for us because manually synthesizing properties is not just boilerplate but also more tedious than doing Quality Testing on the Tickle Me Elmo assembly line.

The other one made me think quite a bit before disabling.

If you are going to disable warnings, make sure you have rational other than “I want the warnings to go away.” or “Stop breaking my beautiful build you bad compiler!”. Here’s an example of the thought process went through.

semicolon-before-method-body: I’ve long, long had the habit of adding semicolons after method name implementations

⤹ HERE!
- (void)doAction:(id)arg;
{
//
}

It makes copying and pasting between header and source files easier. It is optional in ObjC, but a syntax error in plain old C. I’ve found it on the whole to be a good little character, and greater than 99% of the methods I write have it. That being said, I don’t see it that much in the greater ObjC world and could be convinced to change my habits in the future.

For the vast majority of the Xcode-using population, I recommend starting with the following and then disabling warnings as necessary for your own project requirements and coding standards.

-Weverything
-Wno-objc-missing-property-synthesis

Temporarily Overriding Warnings With Our Friend #pragma

Sometimes you just want to disable warnings for a small section of code. This is done with the magic of #pragma. Specifically, the very nice diagnostic push & pop commands.

The item about error numbers leaves me conflicted, however, as they are invaluable during development and can help narrow down errors to specific points in code.

Lastly, something I struggle with is making the API secure vs making it easy to use. You need a balance here. Oauth is so developer-hostile. I personally recommend a scheme similar to Amazon’s S3 service, as well as making everything run over https. One of the primary downsides of https (difficulty caching) doesn’t typically apply to API endpoints.

With respect to error codes, 4XX errors (the API consumer messed up), good error messages are important. Ideally, there should be enough information to help the consumer resolve the issue on their own. One security related message worth mentioning is that it is considered a better practice to combine username/password errors into one generic “Username and/or password is incorrect” type message rather than a separate message for username not found and incorrect passwords.

5XX (the server messed up) error messages should be vague as possible. Too much detail can actually expose you to attacks. I tend to use error numbers for traceability, but no error messages beyond the generic 500 Internal Server Error. If malicious parties are prodding at your API looking for vectors, you are better off treating them like mushrooms: in the dark.

Convenience/Utility Macros

You should have your own set of useful macros that tend to follow you around. These are the one useful enough that I bring them along to new projects.

// Quickly make an NSError
#define AMN_QUICK_ERROR(error_code, error_description)
// Quickly get portrait mode
#define AMN_ORIENTATION_IS_PORTRAIT
// Profiling Macros
// Will log total time elapsed as from START_TIME to CHECK_TIME within a method. The tag must be equal.
#define AMN_START_TIME(tag)
#define AMN_CHECK_TIME(tag)

Log Macros

Debugging is great. But sometimes you need log statements to get a better sense of flow through code. LOG_OBJECT and LOG_METHOD in particular get lots of usage.

These implementations not only log the value of the variable, but the name of the variable as well. LOG_OBJECT(self.id) prints out:

Assertion/Sentinel Macros

Assertion macros are very good for tightening up extremely rare edge cases. You shouldn’t be using assertion as general error handling in Cocoa. In fact, you shouldn’t be using try/catch at all in most Cocoa code; it is not idiomatic. However during development, macros such as ASSERT_IS_CLASS, SHOULD_NEVER_GET_HERE, and ASSERT_NOT_NIL represent a quick, readable way to explicit about intention and also noisily alert during testing.

This particular implementation first prints out an easy to spot header, then follows up with file, line number, object info and an indispensable stack trace.

If you’d like support in the debugger, “Show Breakpoint Navigator”, click the little plus in the bottom left of the window, and then “Add Exception Breakpoint…”. The default values will then cause the debugger to pause upon encountering any assertion.

I was fortunate enough to receive a hard copy of Nathan Barry’sAuthority. I’m going to try something new and post notes on the chapters as I read. If you want a quick recommendation, the answer is: Yes, you should buy this book.

Chapter 1: On Writing

Teach

Marco Polo wasn’t the first to go down Silk Road, but he was the first to write about it.

Rather than having to continue high school for a set number of years, I was given a fixed amount of schoolwork I needed to complete to graduate. I saw that as a checklist and dove in.

If I recall correctly, he finished high school by 15 or 16 years of age.

Don’t wait.

Don’t wait for someone to come to you, and don’t wait for all of life’s ducks to be in a row.

Start Small.

Sacha Greif’s first ebook was only 30 pages long.

Reading in between the lines, the author starts the book off talking about writing. Specifically, when to write (consistently) and what to write (write so that people learn). There is some incidental contact with the whys of writing, but later chapters delve more on the whys & hows of writing.

At some point, nearly every new datastore, programming language or pre-launch platform has been placed on a pedestal of glory somewhere on the internet. These glory stools often show the tech enveloped with rays of sunshine and perfectly placed drops of morning dew highlighting the ideal surface. Every new tech needs promotion to flourish. Yet indiscriminate adoption of solutions that seem relevant to your pain points typically results in that feeling you get when you bite into a warm soft chocolate glazed donut with rocks inside of it. The short-sighted lusting of new hot tech ends up resembling some infernal combination of The Grass is Greener syndrome and blind faith pseudoscience.

It could also be reduced into a somewhat destructive form of optimism.

Your knowledge of your own toolset includes all the warts and melancholy involved with the realities of software development. The difficult-to-source internet quote: “comparing your behind-the-scenes with other’s highlight reels” comes to mind.

When we believe that a new tool will solve all our problems, we fall into the trap of optimistic information asymmetry. We read the blog post or listen to the 45-minute conference talk on how successful a person was in a specific situation, but rarely do we get an equally detailed and realistic discussion on the slope of their learning curve, the anti-patterns or the other myriad of pitfalls.

What does this mean? Should we never use new tech? Of course not. Otherwise, we would be using giant stone pillars for calendars and writing webapps via CGI scripts in perl.

Skepticism, not Cynicism

Optimism is critical to making progress in the face of incomplete information. However, it must be tempered with a healthy dose of skepticism. It is equally important to avoid the pitfalls of cynicism. The Skeptic’s mind can change in the face of evidence. The Cynic is just a narrow-minded pundit who thinks everything sucks.

Do your due diligence. Look for that evidence. Allocate time and manpower for research. Talk to experts or other people who have used the catnip new hot tool/language/environment before. In the age of Twitter, you can usually talk to the people who made the new hot thing.

As the evidence and your familiarity grows, start with small trials of isolated components. Don’t start a company and broadly proclaim that technology X will be the foundation of your new empire – unless you are competing with whatever I do. In that case, please do so. I also have more hot technologies you should know about.

Lastly, always factor in the risk/reward ratio for any new tech. Do the calculus on age, reputation and usefulness of the project. Use your best judgement. Measure the after-effects and don’t be afraid to change course.

Don’t skip the measure part. It is unequivocally the most important part of the feedback loop. Your job is not to use the hot tool - your job is do the best possible work you can.

The internet laughs at the world’s drug-addled cats, not with them. Don’t be a drug-addled cat developer.

Chapter 2: Basic Marketing

Teaching is one of the best ways to market on the web. (My own interpretation is that it also builds trust with your potential customers).

Before you spend months of your life creating something, you may want to test for some demand.

He suggests one author-focused domain for simplicity and to build a personal brand. Many people who make multiple book-focused domains eventually transition back to a single author-focused domain. The reverse doesn’t seem to be true.

Landing Page:

The headline must be clear and compelling. It should have an image & description. An image of a book is important so the reader knows what they are getting. It should definitely have an email signup form.

Seeding interest can be done by harvesting your own network and anyone in the target market who has an audience.

When asking for favors, remember to have an easy out for the recipient. It’s better to keep the relationship warm than be overly forceful for a one-time favor.

Use Wordpress. Anything else is almost certainly wasting time. If you write your own blogging engine, go slap yourself. (My words, not Nathan’s.)

Content

Three Epic Blog Posts

This is actually enough to demonstrate your expertise.

Should be your most valuable information.

Should not be lists or curated content from other places.

Capture Leads: at the end of each post, have your email capture form.

You’d be surprised how little it takes to become perceived as an expert.

Why Email?

Social media is a waste of time for selling.

It can be useful for building relationships.

Email:

You can push content to readers.

It is easier than RSS for readers.

Engagement is higher.

You have ownership.

Each email should provide more value to the reader than to yourself. Otherwise it’s spam and will be treated as such.

Don’t let your list die

a good mailing list needs attention.

skipping a few months is a great way to get a ton of unsubscribes.

He also goes into detail with two case studies:

Brennan Dunn

Jarrod Drysdale

Summary

Teaching is Marketing. Test demand. The classic, recommended method is to use a Wordpress landing page on the internet. Write three epic blog posts. That is enough to begin building trust and expertise. Use email as a second-level filter for customer demand. Love email. Dispense with any preconceived notions you have about email. Email has a lot of mechanical and historical advantages.