Changes between Version 12 and Version 13 of BestPracticeHandbook
- Timestamp:
- May 7, 2015, 9:32:55 AM (7 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
BestPracticeHandbook
v12 v13 19 19 There was very significant divergence in best practices between these libraries at the time of examination, and moreover the divergences were uneven possibly reflecting an uneven understanding of what best practice might be in C++ 11/14. Thence from my examination I have prepared the list below of what I felt were best practices in C++ 11/14 mandatory libraries with hyperlinks to the relevant source code files in the relevant libraries above. As what a "best practice" is or is not may vary according to opinion, I have attempted to provide a rationale for each of the suggestions below. It is up to library authors to weigh each suggestion and to decide whether to apply it, or not, to their library. 20 20 21 One of the most strikingly consistent features of these new libraries is the lack of dependence on Boost, even to the extent of not using the boost namespace as well as no Boost at all. The big advantage of this is modularity, so almost all of these libraries can be used standalone which is an oft requested feature by Boost end users. However this islikely not sustainable as more C++ 11/14 libraries become useful to other C++ 11/14 libraries and coupling therefore increases. I therefore dedicate significant effort below into how to most flexibly couple your library to other libraries to leave options open, the techniques for which have very significantly diversified in C++ 11.21 One of the most strikingly consistent features of these new libraries is the lack of dependence on Boost, even to the extent of not using the boost namespace as well as no Boost at all. The big advantage of this is modularity, so almost all of these libraries can be used standalone which is an oft requested feature by Boost end users. However this form of standalone modularity is more a case of ivory tower syndrome than good design, and is therefore likely not sustainable as more C++ 11/14 libraries become useful to other C++ 11/14 libraries and coupling therefore increases. I therefore dedicate significant effort below into how to most flexibly couple your library to other libraries to leave options open, the techniques for which have very significantly diversified in C++ 11. 22 22 23 23 One will note that the list below is much more C++ 11/14 focused than Boost focused. This is because it is derived from the first crop of C++ 11/14 mandatory Boost libraries. This is not a handbook for writing Boost libraries or even C++ 11/14 Boost libraries, if you want that [http://www.boost.org/development/requirements.html first start reading here] (note some of the guidelines on that page don't really apply to C++ 11/14 libraries) and [http://rrsd.com/blincubator.com/requirements/ then read here] and [http://rrsd.com/blincubator.com/advice/ here]. 24 24 25 I have tried to keep these points generic to all C++ 11/14 libraries in the hope that they are useful far outside Boost. I have also ordered them with what I consider the most important ("strongly consider") first and not as important ("consider") later. 25 I have tried to keep these points generic to all C++ 11/14 libraries in the hope that they are useful far outside Boost. I have also ordered them with what I consider the most important ("strongly consider") first and not as important ("consider") later. The final two points I have marked with "SOAPBOX" because they are short essays discussing fundamental problems in C++ caused mainly by the lack of a well established solution to that problem, and definitively fixing that problem is probably something requiring very significant investment by one of the tech multinationals i.e. it's very hard. 26 26 27 27 [[PageOutline]] … … 310 310 311 311 312 == 8. MAINTENANCE: Consider making it possible to use an XML outputting unit testing framework, even if not enabled by default == 312 == 8. DESIGN: (Strongly) consider using monadic transport types to return state from functions == 313 314 315 == 9. MAINTENANCE: Consider making it possible to use an XML outputting unit testing framework, even if not enabled by default == 313 316 314 317 A very noticeable trend in the libraries reviewed above is that around half use good old C assert() and static_assert() instead of a unit testing framework. … … 390 393 391 394 392 == 9. DESIGN/QUALITY: Consider breaking up your testing into per-commit CI testing, 24 hour soak testing, and parameter fuzz testing ==395 == 10. DESIGN/QUALITY: Consider breaking up your testing into per-commit CI testing, 24 hour soak testing, and parameter fuzz testing == 393 396 394 397 When a library is small, you can generally get away with running all tests per commit, and as that is easier that is usually what one does. … … 405 408 406 409 407 == 1 0. PORTABILITY: Consider not doing compiler feature detection yourself ==410 == 11. PORTABILITY: Consider not doing compiler feature detection yourself == 408 411 409 412 Something extremely noticeable about nearly all the reviewed C++ 11/14 libraries is that they manually do compiler feature detection in their config.hpp, usually via old fashioned compiler version checking. This tendency is not unsurprising as the number of potential C++ compilers your code usually needs to handle has essentially shrunk to three unlike the dozen common compilers implementing the 1998 C++ standard, and the chances are very high that three compilers will be upper bound going into the long term future. This makes compiler version checking a lot more tractable than say fifteen years ago. … … 477 480 478 481 479 == 1 1. CONVENIENCE: Consider having Travis send your unit test code coverage results to Coveralls.io ==480 481 == 1 2. CONVENIENCE: Consider creating a status dashboard for your library with everything you need to know shown in one place ==482 483 == 1 3. COUPLING: Consider enabling multiple versions of your (header only) library to coexist within the same translation unit ==484 485 == 1 4. DESIGN: Consider making (more) use of C++ 11 namespace composure as a design pattern ==486 487 == 1 5. FUTURE PROOFING: Consider using a precompiled header to feed your (multi-abi) library into your unit tests ==482 == 12. CONVENIENCE: Consider having Travis send your unit test code coverage results to Coveralls.io == 483 484 == 13. CONVENIENCE: Consider creating a status dashboard for your library with everything you need to know shown in one place == 485 486 == 14. COUPLING: Consider enabling multiple versions of your (header only) library to coexist within the same translation unit == 487 488 == 15. DESIGN: Consider making (more) use of C++ 11 namespace composure as a design pattern == 489 490 == 16. FUTURE PROOFING: Consider using a precompiled header to feed your (multi-abi) library into your unit tests == 488 491 489 492 Good proxy for supporting C++ Modules down the road, usually a massive build time improvement too especially on low end CPUs. 490 493 491 == 16. COUPLING: Consider allowing your library users to dependency inject your dependencies on other libraries == 492 493 == 17. 494 495 == 18. 496 497 == 19. FUTURE PROOFING: Consider being C++ resumable function ready == 494 == 17. COUPLING: Consider allowing your library users to dependency inject your dependencies on other libraries == 495 496 == 18. FUTURE PROOFING: Consider being C++ resumable function ready == 498 497 499 498 Never block. Never call anything which blocks. … … 503 502 Automatic WinRT friendly. 504 503 505 == 20. COUPLING/SOAPBOX: Essay about pros and consof defaulting to standalone capable (Boost) C++ 11/14 libraries with no external dependencies ==504 == 19. COUPLING/SOAPBOX: Essay about wisdom of defaulting to standalone capable (Boost) C++ 11/14 libraries with no external dependencies == 506 505 507 506 monolithic vs modular 508 507 git submodules vs biicode 508 509 == 20. COUPLING/SOAPBOX: Essay about wisdom of dependency package managers in C++ 11/14 ==