Changes between Version 48 and Version 49 of BestPracticeHandbook
- Timestamp:
- Jun 22, 2015, 2:44:38 PM (7 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
BestPracticeHandbook
v48 v49 107 107 108 108 109 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/strongly-consider-using-git,link=https://muut.com/cppbestpractice/#!/strongly-consider-using-git,alt=Comments)]] 110 111 109 112 == 2. COUPLING: Strongly consider versioning your library's namespace using inline namespaces and requesting users to alias a versioned namespace instead of using it directly == 110 113 … … 220 223 221 224 225 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/strongly-consider-versionin,link=https://muut.com/cppbestpractice/#!/strongly-consider-versionin,alt=Comments)]] 226 227 222 228 == 3. PORTABILITY: Strongly consider trying your library on Microsoft Visual Studio 2015 == 223 229 … … 243 249 244 250 251 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/strongly-consider-trying-yo,link=https://muut.com/cppbestpractice/#!/strongly-consider-trying-yo,alt=Comments)]] 252 253 245 254 == 4. QUALITY: Strongly consider using free CI per-commit testing, even if you have a private CI == 246 255 … … 270 279 2. Other free tooling such as [https://coveralls.io/ Coveralls.io] have built in integration for github and travis. Hooking Jenkins into Coveralls isn't hard, but it "just works" with Travis instead and that's a similar pattern with most free tooling which consumes CI results. 271 280 3. Future tooling by Boost which dashboards Boost libraries and/or ranks libraries by a quality score will almost certainly automate on Travis and Appveyor being queryable by their RESTful APIs. In other words, placing your library in Github and adding Travis and Appveyor CI support has the highest chance of working immediately with any future Boost tooling with minimal additional effort by you. 281 282 283 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/strongly-consider-using-fre,link=https://muut.com/cppbestpractice/#!/strongly-consider-using-fre,alt=Comments)]] 272 284 273 285 … … 308 320 scan-build will run the static analyser and 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. 309 321 322 323 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/strongly-consider-per-commi,link=https://muut.com/cppbestpractice/#!/strongly-consider-per-commi,alt=Comments)]] 324 325 310 326 == 6. QUALITY/SAFETY: Strongly consider running a per-commit pass of your unit tests under both valgrind and the runtime sanitisers == 311 327 … … 334 350 335 351 352 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/strongly-consider-running-a,link=https://muut.com/cppbestpractice/#!/strongly-consider-running-a,alt=Comments)]] 353 354 336 355 == 7. SAFETY: Strongly consider a nightly or weekly input fuzz automated test if your library is able to accept untrusted input == 337 356 … … 341 360 342 361 One of the most promising new input fuzz testing tools going into the long term is LLVM's fuzz testing facilities which are summarised at http://llvm.org/docs/LibFuzzer.html as they make use of the clang sanitiser coverage recording facility to additionally find the code paths least covered, plus the tool is very fast compared to afl. 362 363 364 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/strongly-consider-a-nightly,link=https://muut.com/cppbestpractice/#!/strongly-consider-a-nightly,alt=Comments)]] 343 365 344 366 … … 509 531 510 532 533 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/strongly-consider-using-con,link=https://muut.com/cppbestpractice/#!/strongly-consider-using-con,alt=Comments)]] 534 535 511 536 == 9. MAINTENANCE: Consider making it possible to use an XML outputting unit testing framework, even if not enabled by default == 512 537 … … 589 614 590 615 616 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-making-it-possible,link=https://muut.com/cppbestpractice/#!/consider-making-it-possible,alt=Comments)]] 617 618 591 619 == 10. DESIGN/QUALITY: Consider breaking up your testing into per-commit CI testing, 24 hour soak testing, and parameter fuzz testing == 592 620 … … 602 630 603 631 Regarding parameter fuzz testing, there are a number of tools available for C++, some better or more appropriate to your use case than others. The classic is of course http://ispras.linuxbase.org/index.php/API_Sanity_Autotest, though you'll need [http://ispras.linuxbase.org/index.php/ABI_Compliance_Checker their ABI Compliance Checker] working properly first which has become much easier for C++ 11 code since they recently added GCC 4.8 support (note that GCC 4.8 still has incomplete C++ 14 support). You should combine this with an executable built with, as a minimum, [http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation the address and undefined behaviour sanitisers]. I haven't played with this tool yet with Boost.AFIO, though it is very high on my todo list as I have very little unit testing in AFIO (only functional and integration testing), and fuzz testing of my internal routines would be an excellent way of implementing comprehensive exception safety testing which I am also missing (and feel highly unmotivated to implement by hand). 632 633 634 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-breaking-up-your-t,link=https://muut.com/cppbestpractice/#!/consider-breaking-up-your-t,alt=Comments)]] 604 635 605 636 … … 676 707 677 708 709 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-not-doing-compiler,link=https://muut.com/cppbestpractice/#!/consider-not-doing-compiler,alt=Comments)]] 710 711 678 712 == 12. CONVENIENCE: Consider having Travis send your unit test code coverage results to Coveralls.io == 679 713 … … 754 788 This manually invokes gcov to convert the gcda files into a unified coverage dataset. I then use egrep to include all and egrep -v to exclude anything matching the pattern which is all the stuff not in the actual AFIO library. You'll note I build a JSON fragment as I go into the coverage.json temporary file, and the coverage is generated by chopping up the per line information into a very long string matching the coveralls JSON specification as per its API docs. Do note the separate bit of python called to convert the C++ source code into encoded JSON text (https://github.com/BoostGSoC13/boost.afio/blob/master/test/json_encode.py), I had some problems with UTF-8 in my source code, and forcing them through a ISO-8859 JSON string encode made coveralls happy. I then push the JSON to coveralls using curl. All in all a very blunt instrument, and essentially doing exactly the same thing as the official C++ coveralls tool now does, but you may find the manual method useful if the official tool proves too inflexible for your needs. 755 789 790 791 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-having-travis-send,link=https://muut.com/cppbestpractice/#!/consider-having-travis-send,alt=Comments)]] 792 793 756 794 == 13. CONVENIENCE: Consider creating a status dashboard for your library with everything you need to know shown in one place == 757 795 … … 775 813 776 814 815 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-creating-a-status,link=https://muut.com/cppbestpractice/#!/consider-creating-a-status,alt=Comments)]] 816 777 817 778 818 == 14. USER FRIENDLINESS: Consider letting potential users try your library with a single mouse click == … … 781 821 782 822 783 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-letting-potential,link=https://muut.com/cppbestpractice/#!/consider-letting-potential )]]823 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-letting-potential,link=https://muut.com/cppbestpractice/#!/consider-letting-potential,alt=Comments)]] 784 824 785 825 == 15. DESIGN: Consider making (more) use of ADL C++ namespace composure as a design pattern == … … 928 968 929 969 The above pattern is in fact entirely C++ 03 code and uses no C++ 11. However, template aliasing in C++ 11 makes the above pattern much more flexible. Have a look at https://github.com/ptal/expected/blob/master/include/boost/functional/monads/rebindable.hpp for examples of this ADL invoked namespace composure design pattern. 970 971 972 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-making-use-of-adl,link=https://muut.com/cppbestpractice/#!/consider-making-use-of-adl,alt=Comments)]] 930 973 931 974 … … 1067 1110 1068 1111 If you think of "C++ Modules" as really a somewhat more flexible and reusable implementation of existing precompiled headers which lets the compiler figure out what precompiled parts to use without you manually telling it as you must right now, you can estimate whether it is worth the effort to add support for Modules to your library as the speedup is likely similar to a precompiled header. The clang method is non-intrusive to your source code and doesn't get in the way of older compilers, but adds significant hassle in keeping the module map and the source code in sync. The Microsoft method seems to require a fair bit of #ifdef, but the module specification must be part of the source code which may aid keeping it in sync. 1112 1113 1114 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-defaulting-to-head,link=https://muut.com/cppbestpractice/#!/consider-defaulting-to-head,alt=Comments)]] 1069 1115 1070 1116 … … 1240 1286 In other words, you can reset the configuration macros and reinclude afio.hpp to generate a new configuration of AFIO as many times as you like within the same translation unit. This allows header only library A to require a different configuration of AFIO than header only library B, and it all "just works". As APIBind is currently lacking documentation, I'd suggest you [https://docs.google.com/presentation/d/1badtN7A4lMzDl5i098SHKvlWsQY-tsVcutpq_UlRmFI/pub?start=false&loop=false&delayms=3000 review the C++ Now 2015 slides on the topic] until proper documentation turns up. The procedure is not hard, and you can examine https://github.com/BoostGSoC13/boost.afio/blob/master/include/boost/afio/config.hpp for a working example of it in action. Do watch out for the comments marking the stanzas which are automatically generated by scripting tools in APIBind, writing those by hand would be tedious. 1241 1287 1288 1289 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-allowing-your-libr,link=https://muut.com/cppbestpractice/#!/consider-allowing-your-libr,alt=Comments)]] 1290 1291 1242 1292 == 18. FUTURE PROOFING: Consider being C++ resumable function ready == 1243 1293 … … 1514 1564 1515 1565 1566 [[Image(http://www.nedprod.com/feed/MuutBadge.php?path=/cppbestpractice/consider-being-c-resumabl,link=https://muut.com/cppbestpractice/#!/consider-being-c-resumabl,alt=Comments)]] 1567 1568 1516 1569 == 19. Stuff still being pondered for recommendation here == 1517 1570