Slide 1

Slide 1 text

The Compiler is Your Friend Ali Rantakari HelsinkiOS / CocoaHeads • April 9, 2013

Slide 2

Slide 2 text

Warning Flags

Slide 3

Slide 3 text

Warning Flag Syntax • -Wfoo to enable foo, where foo is the name of a warning, or a grouping of warnings • -Wno-foo to disable the warning foo • -w to disable all warnings (boo!)

Slide 4

Slide 4 text

Warnings = Errors • A valid issue ➡ Fix the issue • Something you don’t care about, or a false positive ➡ Disable the warning (locally or globally) • Something you don’t understand ➡ Figure it out, son // .xcconfig: GCC_TREAT_WARNINGS_AS_ERRORS = YES // cmd-line: -Werror If the compiler warns you about something, it is either:

Slide 5

Slide 5 text

Common Warning Groups • On by default — Always on unless you explicitly disable them. Obviously believed to be useful to everyone, with extremely low false-positive rates • -Wall — There is high confidence in both the value and low false-positive rate of these warnings • -Wextra — These warnings are believed to be valuable and robust (not buggy), but they may have high false- positive rates or common philosophical objections • -Wpedantic — Enforces strict ISO C/C++. • -Weverything — An “insane group” that enables literally every warning in clang (even the buggy, unfinished ones). Meant strictly for clang developers.

Slide 6

Slide 6 text

Useful Warnings Not Included in The Common Groups • -Wshadow — a local variable or type declaration shadows another variable, parameter, type, or class member (in C++), or whenever a built-in function is shadowed int main(int argc, char *argv[]) { if (1 == 1) { int argc = 9; NSLog(@"The int is %i.", argc); } }

Slide 7

Slide 7 text

Useful Warnings Not Included in The Common Groups • -Wfloat-equal — floating-point values are used in equality comparisons float a = 2.0; float b = 3.1; if (a == b) [self doImportantThing];

Slide 8

Slide 8 text

Useful Warnings Not Included in The Common Groups • -Wundef — an undefined identifier is evaluated in an #if directive #if THIS_HAS_NOT_BEEN_DEFINED

Slide 9

Slide 9 text

Useful Warnings Not Included in The Common Groups • -Wempty-body — empty body for if, else, or do while if (1 == 2) { NSLog(@"yo"); } else; { NSLog(@"Guess when I will be evaluated"); }

Slide 10

Slide 10 text

Useful Warnings Not Included in The Common Groups • -Wnewline-eof — no newline before end of file

Slide 11

Slide 11 text

New Warnings in Upcoming Versions of Clang • -Wobjc-literal-compare — Direct comparison of {a string literal / an array literal / a dictionary literal / a numeric literal / a boxed expression} has undefined behavior. Use -isEqual: instead. (on by default) • -Warc-repeated-use-of-weak — Weak {variable / property / implicit property / instance variable} is accessed multiple times in this {function / method / block / lambda} but may be unpredictably set to nil; assign to a strong variable to keep the object alive (not in any common warning group; must explicitly enable) • A bunch of warnings based on annotations you add to your code • A bunch of C++ warnings

Slide 12

Slide 12 text

What Other Warnings Are There? • Unfortunately, Clang’s documentation says “TODO” here. • You can look at GCC’s documentation • Unfortunately some of those warnings are not implemented in Clang, but it will still accept the warning flags without complaint, for “GCC compatibility” • You can look at clang’s source code • include/clang/Basic/DiagnosticGroups.td • include/clang/Basic/DiagnosticSemaKinds.td

Slide 13

Slide 13 text

Disabling a Warning Completely • Find out what the warning flag name is • Disable with -Wno-flagname

Slide 14

Slide 14 text

Disabling a Warning Locally #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wstupid-method-name" - (BOOL) doTheThingWithTheOtherThing { } #pragma clang diagnostic pop

Slide 15

Slide 15 text

Disabling a Warning Locally: -Wunused-parameter - (void) doThingWithObject:(NSObject* __attribute__((unused)))thingie { NSLog(@"allo gov'nor"); } - (void) doThingWithObject:(NSObject* __unused)thingie { NSLog(@"allo gov'nor"); } - (void) doThingWithObject:(NSObject*)thingie { #pragma unused(thingie) NSLog(@"allo gov'nor"); } test.m:8:39: warning: unused parameter 'thingie' [-Wunused-parameter] - (void) doThingWithObject:(NSObject*)thingie ^ 1 warning generated.

Slide 16

Slide 16 text

Disabling Warnings in Third- Party Code

Slide 17

Slide 17 text

Disabling Warnings in Third- Party Headers // libfoo_imports.h #pragma once // Suppress warnings by pretending this is a system header #pragma GCC system_header #pragma clang system_header #import "libfoo.h" // MyCode.m #import "libfoo_imports.h"

Slide 18

Slide 18 text

In Conclusion • Treat warnings as errors (-Werror) • Use at least -Wall and -Wextra • You can try -Weverything to see what else there is, but you probably don’t want to leave it on • If third-party code triggers your warnings, don’t completely disable the warnings for all of your code — there are easy ways around this • The compiler loves you and wants to help you out — let it!

Slide 19

Slide 19 text

A few source links http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html http://programmers.stackexchange.com/a/124574/14135