Changes between Version 22 and Version 23 of BestPracticeHandbook


Ignore:
Timestamp:
May 13, 2015, 11:45:40 PM (7 years ago)
Author:
Niall Douglas
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • BestPracticeHandbook

    v22 v23  
    263263== 5. QUALITY: Strongly consider per-commit compiling your code with static analysis tools ==
    264264
    265 In Travis and Appveyor it is easy to configure a special build job which uses the clang static analyser on Linux/OS X and the MSVC static analyser on Windows. These perform lengthy additional static AST analysis tests to detect when your code is doing something stupid and the use of these is an excellent sign that the developer cares about code quality. Static analysis is perfectly suited to be run by a CI as it takes extra time to compile your program, so a CI can trundle off and do the lengthy work itself while you get on with other work.
     265In Travis and Appveyor it is easy to configure a special build job which uses the clang static analyser and clang lint tools on Linux/OS X and the MSVC static analyser on Windows. These perform lengthy additional static AST analysis tests to detect when your code is doing something stupid and the use of these is an excellent sign that the developer cares about code quality. Static analysis is perfectly suited to be run by a CI as it takes extra time to compile your program, so a CI can trundle off and do the lengthy work itself while you get on with other work.
    266266
    267267Enabling Microsoft's static analyser is easy, simply add /analyze to the compiler command line. Your compile will take ten times longer and new warnings will appear. Note though that the MSVC static analyser is quite prone to false positives like miscounting array entries consumed. You can suppress those using the standard #pragma warning(disable: XXX) system around the offending code.
     
    286286
    287287scan-build will generate a HTML report of the issues found with a pretty graphical display of the logic followed by the analyser into the $REPORTS directory. Jenkins has a plugin which can publish this HTML report for you per build, for other CIs you'll need to copy the generated files onto a website somewhere e.g. committing them to your repo under gh-pages and pushing them back to github.
     288
     289Finally, the clang lint tool (called [http://clang.llvm.org/extra/clang-tidy.html clang-tidy]) is not something I have currently enabled in my own code, but it looks very promising. The following checks are default enabled on clang tidy 3.6:
     290
     291{{{
     292Enabled checks:
     293    clang-analyzer-core.CallAndMessage
     294    clang-analyzer-core.DivideZero
     295    clang-analyzer-core.DynamicTypePropagation
     296    clang-analyzer-core.NonNullParamChecker
     297    clang-analyzer-core.NullDereference
     298    clang-analyzer-core.StackAddressEscape
     299    clang-analyzer-core.UndefinedBinaryOperatorResult
     300    clang-analyzer-core.VLASize
     301    clang-analyzer-core.builtin.BuiltinFunctions
     302    clang-analyzer-core.builtin.NoReturnFunctions
     303    clang-analyzer-core.uninitialized.ArraySubscript
     304    clang-analyzer-core.uninitialized.Assign
     305    clang-analyzer-core.uninitialized.Branch
     306    clang-analyzer-core.uninitialized.CapturedBlockVariable
     307    clang-analyzer-core.uninitialized.UndefReturn
     308    clang-analyzer-cplusplus.NewDelete
     309    clang-analyzer-cplusplus.NewDeleteLeaks
     310    clang-analyzer-deadcode.DeadStores
     311    clang-analyzer-llvm.Conventions
     312    clang-analyzer-security.FloatLoopCounter
     313    clang-analyzer-security.insecureAPI.UncheckedReturn
     314    clang-analyzer-security.insecureAPI.getpw
     315    clang-analyzer-security.insecureAPI.gets
     316    clang-analyzer-security.insecureAPI.mkstemp
     317    clang-analyzer-security.insecureAPI.mktemp
     318    clang-analyzer-security.insecureAPI.rand
     319    clang-analyzer-security.insecureAPI.strcpy
     320    clang-analyzer-security.insecureAPI.vfork
     321    clang-analyzer-unix.API
     322    clang-analyzer-unix.Malloc
     323    clang-analyzer-unix.MallocSizeof
     324    clang-analyzer-unix.MismatchedDeallocator
     325    clang-analyzer-unix.cstring.BadSizeArg
     326    clang-analyzer-unix.cstring.NullArg
     327}}}
     328
     329I also see some default disabled checks which might be interesting:
     330
     331{{{
     332    clang-analyzer-alpha.core.BoolAssignment
     333    clang-analyzer-alpha.core.CallAndMessageUnInitRefArg
     334    clang-analyzer-alpha.core.CastSize
     335    clang-analyzer-alpha.core.CastToStruct
     336    clang-analyzer-alpha.core.FixedAddr
     337    clang-analyzer-alpha.core.IdenticalExpr
     338    clang-analyzer-alpha.core.PointerArithm
     339    clang-analyzer-alpha.core.PointerSub
     340    clang-analyzer-alpha.core.SizeofPtr
     341    clang-analyzer-alpha.core.TestAfterDivZero
     342    clang-analyzer-alpha.cplusplus.VirtualCall
     343    clang-analyzer-alpha.deadcode.UnreachableCode
     344    misc-argument-comment
     345    misc-bool-pointer-implicit-conversion
     346    misc-swapped-arguments
     347    misc-undelegated-constructor
     348    misc-uniqueptr-reset-release
     349    misc-unused-raii
     350    misc-use-override
     351    readability-braces-around-statements
     352    readability-function-size
     353    readability-redundant-smartptr-get
     354}}}
    288355
    289356
     
    865932== 15. BUILD: Consider defaulting to header only, but actively manage facilities for reducing build times ==
    866933
     934Making your library header only is incredibly convenient for your users - they simply drop in a copy of your project and get to work, no build system worries. Hence most Boost libraries and many C++ libraries are header only capable, often header only default. A minority are even header only only.
     935
     936One thing noticed in the library review is just how many of the new C++ 11/14 libraries are header only only, and whilst convenient I think library authors should and moreover ''can'' do better. For some statistics to put this in perspective, proposed Boost.AFIO v1.3 provides a range of build configurations for its unit tests:
     937
     9381. Header only
     9392. Precompiled header only (default)
     9403. Precompiled not header only (library implementation put into a shared library)
     9414. Precompiled header only with link time optimisation
     942
    867943||= Build flags =||= Microsoft Windows 8.1 x64 with Visual Studio 2013 =||= Ubuntu 14.04 LTS Linux x64 with GCC 4.9 and gold linker =||= Ubuntu 14.04 LTS Linux x64 with clang 3.4 and gold linker =||
    868944|| Debug header only                   ||  7m17s || 12m0s  || 5m45s ||
     945|| Debug precompiled header only       ||  2m10s || 10m26s || 5m46s ||
    869946|| Debug precompiled not header only   ||  0m55s ||  3m53s || asio failure ||
     947|| Release precompiled header only     ||  2m58s ||  9m57s || 8m10s ||
    870948|| Release precompiled not header only ||  1m10s ||  3m22s || asio failure ||
    871 || Debug precompiled header only       ||  2m10s || 10m26s || 5m46s ||
    872 || Release precompiled header only     ||  2m58s ||  9m57s || 8m10s ||
    873 || Debug precompiled header only link time optimisation    || 5m37s || GCC ICE ||  5m42s ||
    874949|| Release precompiled header only link time optimisation  || 7m30s || 13m0s   ||  8m11s ||
     950
     951These are for a single core 3.9Ghz i7-3770K computer. I think the results speak for themselves, and note that AFIO is only 8k lines with not much metaprogramming.
     952
     953The approaches for improving build times for your library users are generally as follows:
     954
     955TODO
    875956
    876957== 16. COUPLING: Consider allowing your library users to dependency inject your dependencies on other libraries ==