Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Compiler is Your Friend

The Compiler is Your Friend

Presented at the HelsinkiOS/CocoaHeads developer meetup, April 2013

D15666558763fe2deffd703eeff36761?s=128

Ali Rantakari

April 09, 2013
Tweet

Transcript

  1. The Compiler is Your Friend Ali Rantakari HelsinkiOS / CocoaHeads

    • April 9, 2013
  2. Warning Flags

  3. 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!)
  4. 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:
  5. 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.
  6. 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); } }
  7. 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];
  8. Useful Warnings Not Included in The Common Groups • -Wundef

    — an undefined identifier is evaluated in an #if directive #if THIS_HAS_NOT_BEEN_DEFINED
  9. 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"); }
  10. Useful Warnings Not Included in The Common Groups • -Wnewline-eof

    — no newline before end of file
  11. 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
  12. 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
  13. Disabling a Warning Completely • Find out what the warning

    flag name is • Disable with -Wno-flagname
  14. Disabling a Warning Locally #pragma clang diagnostic push #pragma clang

    diagnostic ignored "-Wstupid-method-name" - (BOOL) doTheThingWithTheOtherThing { } #pragma clang diagnostic pop
  15. 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.
  16. Disabling Warnings in Third- Party Code

  17. 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"
  18. 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!
  19. A few source links http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html http://programmers.stackexchange.com/a/124574/14135