Clang Diagnostics
Diagnostics combine logic with analytics to arrive at a conclusion. It’s science and engineering at their purest. It’s human reasoning at its most potent.
Within the medical profession, a diagnosis is made through instinct backed by lab samples. For industrial manufacturing, one diagnoses a product fault through an equal application of statistics and gumption.
For us developers, our medium of code informs the production of subsequent code, creating a positive feedback loop that has catapulted the development of technology exponentially over the last half century. For us Objective-C developers specifically, the most effective diagnostics come from Clang.
Clang is the C / Objective-C front-end to the LLVM compiler. It has a deep understanding of the syntax and semantics of Objective-C, and is much of the reason that Objective-C is such a capable language today.
That amazing readout you get when you “Build & Analyze” (⌘⇧B
) is a function of the softer, more contemplative side of Clang: its code diagnostics.
In our article about #pragma
, we quipped:
Pro tip: Try setting the
-Weverything
flag and checking the “Treat Warnings as Errors” box your build settings. This turns on Hard Mode in Xcode.
Now, we stand by this advice, and encourage other developers to step up their game and treat build warnings more seriously. However, there are some situations in which you and Clang reach an impasse. For example, consider the following switch
statement:
switch (style) {
case UITable View Cell Style Default:
case UITable View Cell Style Value1:
case UITable View Cell Style Value2:
case UITable View Cell Style Subtitle:
…
default:
return;
}
When certain flags are enabled, Clang will complain that the “default label in switch which covers all enumeration values”. However, if we know that, zooming out into a larger context, style
is (for better or worse) derived from an external representation (e.g. JSON resource) that allows for unconstrained NSInteger
values, the default
case is a necessary safeguard. The only way to insist on this inevitability is to use #pragma
to ignore a warning flag temporarily:
push
&pop
are used to save and restore the compiler state, similar to Core Graphics or OpenGL contexts.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcovered-switch-default"
switch (style) {
case UITable View Cell Style Default:
case UITable View Cell Style Value1:
case UITable View Cell Style Value2:
case UITable View Cell Style Subtitle:
…
default:
return;
}
#pragma clang diagnostic pop
Again, and this cannot be stressed enough, Clang is right at least 99% of the time. Actually fixing an analyzer warning is strongly preferred to ignoring it. Use
#pragma clang diagnostic ignored
as a method of last resort.
This week, as a public service, we’ve compiled a (mostly) comprehensive list of Clang warning strings and their associated flags, which can be found here:
You can also find the compiler and analyzer flags for any warning you might encounter by ^
-Clicking the corresponding entry in the Xcode Issue Navigator and selecting “Reveal in Log”. (If this option is disabled, try building the project again).