Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Â
An Introduction to PC-Lint
1. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
1/47
An Introduction to PC-lint
Agenda:
âș Introduction
âș Features
âș Usage
âș The true value of PC-lint
Version 1.20
2. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
2/47
âC makes it easy to shoot yourself in the foot...â
(Bjarne Stroustrup)
An Introduction to PC-lint
C is a powerful
but dangerous
language
3. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
3/47
Classic C Mistakes
Only to name a few...
âș Array out-of-bounds access
âș Null pointer dereferencing
âș Using a variable before initialization
âș Order of evaluation of operands
âș Integer overflow
âș Assignment where check for equality was intended
âș Illegal printf/scanf format strings
âș Forgetting to handle a case in switch statement
âș Passing macro arguments with side effects
4. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
4/47
â ...C++ makes it harder, but when you do,
it blows your whole leg off.â
(Bjarne Stroustrup)
An Introduction to PC-lint
The same holds
for C++
5. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
5/47
Classic C++ Mistakes
Only to name a few...
âș Forgetting to initialize class members
âș Initializing class members in the wrong order
âș Forgetting to declare the base class destructor virtual
âș Forgetting to implement the assignment op
âș Using auto_ptr on containers
âș Memory and resource leaks
âș Unhandled exceptions
âș Leaking exceptions from destructors
âș Order of static initialization
6. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
6/47
The Case For Static Code Checking
C and C++ are powerful but dangerous
Even if code works, it might not be portable/future-proof
âș Alignment issues
âș Size of scalars
âș Compiler-specific features
âș âŠ
Traditional testing (checking at run-time)
âș Might not detect all issues
âș Is expensive
However: static checking
is not meant as a
replacement for testing!
7. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
7/47
What is Lint/PC-lint?
Lint
âș Etymology: undesired fibers and fluff in sheep's wool
âș Seventh version (V7) of Unix (1979)
âș Part of PCC (portable C compiler)
PC-lint
âș Commercial version for C and C++
âș Produced by Gimpel Software, USA.
âș First version appeared 1985
âș Current version is 9.00
âș FlexeLint: for Unix/Linux
8. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
8/47
What is Lint/PC-lint?
PC-lint
âș Works similar to a compiler
âș Checks code statically ('at compile-time')
âș Doesn't produce machine code
âș Performs thousands of checks and will produce the appropriate
warnings, so-called "issues" or "messages
9. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
9/47
Examples
Let's have a look at some code...
10. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
10/47
What's wrong with this C code?
1 #include <stdio.h>
2 #define SUM(x, y) (x) + (y)
3 unsigned long* PerformGizmoAlgorithm(int a, int b) {
4 unsigned long vector[8] = {143, 33, 2l, 76, 83, 222, 45, 45};
5 int i;
6
7 for (i = 0; i < 8; ++i);
8 vector[i + 1] = vector[i] * SUM(a, b);
9
10 return vector;
11 }
11. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
11/47
What's wrong with this C code?
1 #include <stdio.h>
2 #define SUM(x, y) (x) + (y)
3 unsigned long* PerformGizmoAlgorithm(int a, int b) {
4 unsigned long vector[8] = {143, 33, 2l, 76, 83, 222, 45, 45};
5 int i;
6
7 for (i = 0; i < 8; ++i);
8 vector[i + 1] = vector[i] * SUM(a, b);
9
10 return vector;
11 }
file.c:2 I 773 Expression-like macro 'SUM' not parenthesized
file.c:7 I 722 Suspicious use of ;
file.c:8 W 539 Did not expect positive indentation from line 7
file.c:8 I 737 Loss of sign in promotion from int to unsigned long
file.c:8 W 661 Possible access of out-of-bounds pointer (1 beyond end of data) by operator '['
file.c:8 W 661 Possible access of out-of-bounds pointer (2 beyond end of data) by operator '['
file.c:10 W 604 Returning address of auto variable 'vector'
file.c:0 I 766 Header file '/usr/include/stdio.h' not used in module 'file.c'
file.c:4 W 620 Suspicious constant (L or one?)
Would you have
found all of these
issues?
12. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
12/47
What's wrong with this C++ code?
1 class Base {
2 char* mp;
3 int mCount;
4 public:
5 Base(int aCount = 0) { mCount = aCount; if(mCount > 0) mp = new char[mCount]; }
6 void printRuntimeType() { cout << "Base"; }
7 ~Base() { delete mp; }
8 };
9
10 class Derived : public Base {
11 public:
12 void printRuntimeType() { cout << "Derived"; }
13 };
13. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
13/47
What's wrong with this C++ code?
1 class Base {
2 char* mp;
3 int mCount;
4 public:
5 Base(int aCount = 0) { mCount = aCount; if(mCount > 0) mp = new char[mCount]; }
6 void printRuntimeType() { cout << "Base"; }
7 ~Base() { delete mp; }
8 };
9
10 class Derived : public Base {
11 public:
12 void printRuntimeType() { cout << "Derived"; }
13 };
file.cpp:5 I 1732 new in constructor for class Base which has no assignment operator
file.cpp:5 I 1733 new in constructor for class Base which has no copy constructor
file.cpp:5 I 737 Loss of sign in promotion from int to unsigned int
file.cpp:5 W 1541 Member Base::mp (line 4) possibly not initialized by constructor
file.cpp:7 W 424 Inappropriate deallocation (delete) for 'new[]' data.
file.cpp:12 W 1511 Member hides non-virtual member Base::printRuntimeType(void) (line 8)
file.cpp:13 W 1509 base class destructor for class 'Base' is not virtual
Would you have
found all of these
issues?
14. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
14/47
What PC-lint is Not
Focus is on finding C/C++ programming errors:
âș No: Java, C#
âș No: Metrics
âș No: High-level design and architectural analysis
Inexpensive, compact but powerful code checker:
âș No: GUI/browsers/wizards
âș No: Issue database
âș No: License server
15. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
15/47
Features
A quick tour of some features
âș Weak definials
âș Const-correctness
âș Strong types
âș Value tracking
âș Semantics
âș Multi-thread support
âș Author files and MISRA
16. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
16/47
Weak definials
PC-lint keeps code (esp. interfaces) clean by reporting
âș Unused declarations (types, macros...)
âș Unused or redundantly included headers
âș Declarations that are only used locally
âș
Move from header to .c/.cpp file
âș
Make functions/objects static
17. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
17/47
Const-correctness
Const-correctness is an important topic in C/C++
Difficult to add const-correctness later (ripple effect)
PC-lint reports:
âș Member function could be made const
âș Pointer could be declared as pointing to const
âș Even: parameters/objects could be made const
18. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
18/47
Strong types
Neither C nor C++ has strong typing
âș Mixing enums, ints, bools, typedefs is permissible
'Strong type' feature lets you selectively enable strong type
checking
typedef int Temperature;
int t1 = 42;
Temperature t2 = t1; // Bad!
if (t1) { // Bad!
...
}
Compatibility of types can be achieved through the 'type
hierarchy' feature
19. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
19/47
Value tracking
PC-lint keeps track of variable values and initialization status:
extern int g_array[10];
int foo(int* arr, int n) { return arr[n]; }
...
if (count == 20) {
cout << "Wow, 20 elements!" << endl;
}
int y = foo(g_array, 20); // -passes(2): likely out-of-bounds access
int x = foo(g_array, count); // -passes(2): possible out-of-bounds access
The more passes, the better (but slower!)
20. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
20/47
Many well-known library functions have certain pre-/postconditions:
âș assert(), abort(): never return
âș memset(): arg3 may not exceed sizeof arg1 area
âș strcpy(): return value is never NULL
âș fopen(): args never NULL and '0' terminated; return value may be NULL
Transfer such well-known semantics to user-defined functions
âș -function(abort, MyClass::stop)
PC-lint uses additional information during analysis
mc->stop();
foo(42); // Unreachable code!
Semantics -- function mimicry
21. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
21/47
Semantics -- semantic specifications
Function mimicry is based on "semantic specifications"
Use semantic specifications for finer-grained control
Many, many possibilities via -sem option:
r_null, r_no, nulterm(#), #p, inout, thread, thread_unsafe...
Example:
//lint -sem(decode, inout(3))
result_t decode(const void* src, void* dest, int* destLen);
void foo() {
int n;
if (decode(inbuf, outbuf, &n) == OK) { // n not initialized
...
}
}
22. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
22/47
Based on "semantic specifications", specify:
âș Thread root functions
âș Thread creation functions (eg. pthread_create())
âș Begin of thread protected region (eg. pthread_mutex_lock)
âș End of thread protected region (eg. pthread_mutex_unlock)
âș Thread-safe, thread-unsafe functions
PC-lint reports:
âș Unprotected access to static/global data/objects
âș Unprotected calls to thread-unsafe functions
âș Mismatched lock/unlock calls
Multi-thread support
23. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
23/47
Option files with checks recommended by authors:
âș Mainly Scott Meyers, "(More) Effective C++" (au-sm*.lnt)
âș Checks for 64-bit issues (au-64.lnt)
âș MISRA recommendations:
âș MISRA C 1998 (au-misra1.lnt)
âș MISRA C 2004 (au-misra2.lnt)
âș MISRA C 2012 (au-misra3.lnt)
âș MISRA C++ (au-misra-cpp.lnt)
Author files and MISRA
24. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
24/47
Usage
Usage
âș Command-line interface
âș Lint messages
âș Lint policy
âș Message inhibition
25. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
25/47
Command-line interface
lint-nt.exe <args>... <files>...
âș lint-nt.exe -w3 -I../include main.cpp calc.cpp
Pass options directly or via option file (*.lnt)
âș lint-nt.exe settings.lnt main.cpp calc.cpp
âș lint-nt.exe settings.lnt files.lnt
Two modes of operation
âș Single checkout mode (-u)
âș
lint-nt.exe settings.lnt -u calc.cpp
âș
Good for quick checks of a single module
âș Whole-project mode (w/o -u)
âș
Slower, but Lint analysis is much deeper
âș
PC-lint knows if and how functions/identifiers are used across translation units
26. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
26/47
Command-line interface
PC-lint output
âș Can be tuned
âș "Message presentation options" define what and how issues are
reported
âș Call PC-lint from within your favorite editor/IDE to navigate code/issues
âș Select env-*.lnt files that match your IDE's error parser, e. g.
env-vc9.lnt, env-vim.lnt, env-xml.lnt, env-html.lnt
27. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
27/47
Lint messages
Lint produces around 1000 different warnings
Let's review our previous example...
Kind C C++ Level Think...
Syntax Errors 1 - 199 1001 - 1199 1 Syntax Error
Internal Errors 200 - 299 1200 - 1299 Oops!
Fatal Errors 300 - 399 Oops!
Warnings 400 - 699 1400 - 1699 2 Something likely wrong
Informational 700 - 899 1700 - 1899 3 Something might be wrong
Elective Notes 900 - 999 1900 - 1999 4 Style issue
28. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
28/47
What's wrong with this C code?
1 #include <stdio.h>
2 #define SUM(x, y) (x) + (y)
3 unsigned long* PerformGizmoAlgorithm(int a, int b) {
4 unsigned long vector[8] = {143, 33, 2l, 76, 83, 222, 45, 45};
5 int i;
6
7 for (i = 0; i < 8; ++i);
8 vector[i + 1] = vector[i] * SUM(a, b);
9
10 return vector;
11 }
file.c:2 I 773 Expression-like macro 'SUM' not parenthesized
file.c:7 I 722 Suspicious use of ;
file.c:8 W 539 Did not expect positive indentation from line 7
file.c:8 I 737 Loss of sign in promotion from int to unsigned long
file.c:8 W 661 Possible access of out-of-bounds pointer (1 beyond end of data) by operator '['
file.c:8 W 661 Possible access of out-of-bounds pointer (2 beyond end of data) by operator '['
file.c:10 W 604 Returning address of auto variable 'vector'
file.c:0 I 766 Header file '/usr/include/stdio.h' not used in module 'file.c'
file.c:4 W 620 Suspicious constant (L or one?)
Some 'informationals'
are clearly bugs
in this context!
29. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
29/47
Enabling/disabling messages
Coarse level: -w<level> option
âș Example: -w3 // Set warning level to 3.
Fine level: [+-]e<number>
âș Example: +e1509 // Warn on non-virtual base class d-tor.
âș Example: -e801 // Using 'goto' is fine.
âUser Lint Policyâ defines the right mix...
30. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
30/47
User Lint policy
The user Lint policy...
âș is a text file containing global PC-lint settings for a project
âș is fed to PC-lint during a Lint run
âș mostly consists of message-related settings
âș base warning level (e. g. 3) plus/minus many exceptions
âș is not cast in stone but evolves over time
âș allows for local overriding of settings in source files
31. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
31/47
Lint policy example
-function(__assert, ASSERT) // copy semantics of assert()
-strong(b,boolean) // BOOLEAN is of type boolean
+macros // enable long lines
-wlib(1) // in lib headers report only errors
-w3 // warning level 3
-A // strict ANSI
+fpn // argument pointers might be NULL
-esym(534,*printf) // often called without checking return
-esym(534,*strncat,*strncpy) // often called without checking return
-esym(534,*strcpy) // often called without checking return
-epn // nominally differing ptrs
-e787 // non-exhaustive switch
-e788 // non-exhaustive switch
-e508 // extern with definition
-e641 // enum to int conversion
-e730 // boolean arg to function
-e46 // fields other than int
-e655 // bit-wise operator used with enums
-"esym(793, external identifiers)" // don't complain about more than 511 external
...
32. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
32/47
Message inhibition
How to get rid of unwanted messages:
âș Fully understand what PC-lint is saying (consult msg.txt)
âș Modify the code (carefully!)
âș Fix indentation
âș Parenthesize
âș
Use assertions
âș cast
âș Suppress locally via inhibition comments
(next slide)
âș Last resort: #ifdef _lint
âș Consider making (suggesting) changes to the Lint Policy
33. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
33/47
Inhibition within source code
Options within Lint comments:
âș within source code: /*lint ... */ or //lint ...
âș Note! No blank before 'lint' keyword!
//lint -e{888} hollyr: Needed for performance optimization
x = foo() * bar() - a;
Various variants exist that limit the scope of an inhibition
34. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
34/47
Inhibition comments
Next expression suppression:
a = /*lint -e(413) dereferencing 0 is OK */ *(char*)0);
One-line suppression:
if (x = f(34)) //lint !e720 boolean test of assignment is OK
y = y / x;
Within-a-macro suppression:
//lint -emacro(732, MULTIPLY) suppress loss of sign for macro MULTIPLY
Suppression for a particular symbol:
//lint -esym(754, MyClass::foo) suppress 'foo' not referenced
There are many, many more (see chapter 5.2 of PC-lint manual)
Advice: always use the narrowest inhibition scope possible!
35. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
35/47
The true value of PC-lint
Q: What's the purpose of using PC-lint?
A: Find bugs, of course!
36. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
36/47
When to use PC-lint?
1. Check-out
2. Coding
3. Developer testing
4. Check-in
5. Nightly/daily build
6. Integration testing
7. System testing
8. Release
here!
38. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
38/47
When linting late in the life-cycle
Code has already been tested and debugged
âș Lots of effort has been spent (wasted) already
âș Mostly only âfalse positivesâ left
Big mental distance
âș Hard to remember the change
âș Reluctance to change existing (working) code
âș
Fear of introducing real bugs
âș
Pride!
Developers often blindly dismiss warnings as âfalse positivesâ
39. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
39/47
When linting early in the life-cycle
Less time wasted on debugging
PC-lint acts as a coach
âș Reviews code, criticizes
âș
âsoftware consciousnessâ
âș Teaches C/C++ best practices
âș
Over time, developers become better developers
PC-lint encourages developers to review their own code
âș Often, even unrelated problems are found
Low mental distance
Low pride
Code is cleaned-up, rewritten, quality increased
40. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
40/47
How many lint warnings are acceptable?
0
41. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
41/47
âZero Warningsâ process
No warnings allowed when checking-in code
No âcan't see the forest for the treesâ effects
âș Developers see only their issues
No tracking of PC-lint issues
âș Management-free
No mental distance
âș Issues must be resolved, now!
42. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
42/47
The true value of PC-lint
Q: What's the purpose of using PC-lint?
A: Prevent bugs and keep technical debt low!
This is Ward Cunningham,
inventor of the technical
debt metaphor.
My hero!
43. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
43/47
False positives
âIn previously unlinted code, you may get a
discouragingly large number of messagesâ
The PC-lint Manual
44. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
44/47
False positives
1 #define ADD(x, y) x + y
2 #define MUL(x, y) x * y
3
4 class Base {
5 public:
6 Base(int i) : _i(i) { }
7 int add(int a, int b) { return ADD(a, b); }
8 ~Base() { /* ... */ }
9 private:
10 int _i;
11 };
12
13 class Derived : public Base {
14 };
false_positives.cpp:1 Info 773: Expression-like macro 'ADD' not parenthesized
false_positives.cpp:2 Info 773: Expression-like macro 'MUL' not parenthesized
false_positives.cpp:6 Note 1931: Constructor 'Base::Base(int)' can be used for implicit conversions
false_positives.cpp:7 Info 1762: Member function 'Base::add(int, int)' could be made const
false_positives.cpp:4 Info 1712: default constructor not defined for class 'Base'
false_positives.cpp:4 Info 1790: Base class 'Base' has no non-destructor virtual functions
false_positives.cpp:8 Warning 1509: base class destructor for class 'Base' is not virtual
false_positives.cpp:8 Warning 1512: destructor for base class 'Base' is not virtual
false_positives.cpp:2 Info 750: local macro 'MUL' not referenced
45. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
45/47
False positives
Based on the wrong notion about PC-lint
âș Confusing âpreventingâ bugs with âfindingâ bugs
Almost every Lint warning is valuable
âș Highlights technical debt
âș If PC-lint has difficulties understanding code, another developer might
have as well
âș Prevents future problems
âș Self-reviews
46. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
46/47
Some final thoughts...
PC-lint is more about preventing bugs than about finding bugs
Not a magic weapon but another step towards higher quality
Use PC-lint as early as possible in your life-cycle
Try hard to understand what PC-lint is trying to say
Prefer rewriting code over suppression comments
Keep the number of warnings at all times at zero
PC-lint is your friend, not your enemy!
47. An Introduction to PC-lint Licensed under CC BY-NC-ND 3.0 by Ralf Holly Software Consulting
47/47
License
This presentation is licensed under the terms of the
Creative Commons - Attribution - Non Commercial - No Derivatives license.
See http://creativecommons.org/licenses/by-nc-nd/3.0/legalcode for details.