Skip to content

18 Summary of Dos and Don'ts

JackHeeley edited this page Dec 5, 2020 · 19 revisions

Summary of Dos and Don'ts

  1. Do familiarise yourself with this quality reference, (so that you fully understand these dos and don'ts).
  2. Do manage life-cycle costs by requiring teams to agree standards of code hygiene (such as these dos and don'ts).
  3. Do communicate general design constraints, and identify different constraints affecting different types of code.
  4. Do make unit testing and peer reviewing an integral part of every developer's job.
  5. Do measure track and try to improve unit test and peer review coverage and effectiveness.
  6. Do revise this checklist regularly.
  7. Do have a clearly specified set of target environments.
  8. Do select and maintain a viable re-usability strategy.
  9. Don't embed platform dependencies into business logic.
  10. Do use encapsulation to hide complexity, and consider matching architectural components with domain expertise.
  11. Do adopt a balanced architecture with decomposition in layers (depth and width guided by less-than-five rule).
  12. Do apply PIMPL pattern to decouple client from implementation, and to allow each to change independently.
  13. Don't use Boost unless you really have a strong reason, and until you have considered alternatives.
  14. Do identify cross-cutting issues and have a consistent response to them.
  15. Do use utf8-everywhere paradigm.
  16. Do use RAII, and structured exception handling.
  17. Do prepare a logging strategy early.
  18. Do use test-driven development.
  19. Do set and track test coverage targets.
  20. Don't let platform dependencies limit portability of tests of business logic.
  21. Don't include platform headers in business logic code.
  22. Do use ISO C++17 with STL and GSL for business logic.
  23. Do provide domain specific functional support libraries.
  24. Don't expect RAII techniques to restore system state (processes can be signalled to stop abruptly).
  25. Do develop unit tests in parallel with deliverable code.
  26. Do consider unit tests and deliverable code as integral when planning and budgetting.
  27. Do extend unit tests to maintain and improve coverage.
  28. Do regularly measure unit test coverage.
  29. Don't check-in code without an assessment procedure.
  30. Do include peer review as a check-in time requirement.
  31. Do include unit-test results as a check-in time requirement.
  32. Do invest in people. Select the best possible tools, and provide time and budget for training.
  33. Do express important checklist points in multiple ways to provide clarity, emphasis and attention.
  34. Don't expect to learn modern c++ on-the-job.
  35. Do take time to revise templates. To troubleshoot your code effectively it helps to read and understand STL.
  36. Don't rely on comment statements for code understanding, and don't over comment.
  37. Do use intellisense to comment public class functions parameters and return values in headers.
  38. Do use smart pointers and avoid raw pointers (except with legacy API's).
  39. Don't try to learn modern c++ on-the-job.
  40. Do take time to study modern c++ language, STL and GSL.
  41. Do take time to understand C++ Core guidelines, and use static analyzers to assess your code.
  42. Do read and assess UTF-8 manifesto, and follow utf-8 everywhere programming rules.
  43. Don't embed naked operating system calls into business logic.
  44. Do continously attend to analysis and design in agile projects
  45. Do regularly assess and manage structure and modularity.
  46. Don't choose a flat architecture, but do balanced decomposition, in some depth, to less-than-five guidelines.
  47. Do watch for emerging trends in interface counts and complexity.
  48. Do establish early how language and tools (eg namespaces and libraries) will act as containers for architectural components.
  49. Don't forget that goal of encapsulation is to hide complexity, and to limit (localize) need for specific domain expertises.
  50. Do invest time in selecting the best names for component libraries classes functions and data members.
  51. Do recognise difficulties in making name selection as a strong indicator of a weakness in design concept or decomposition.
  52. Don't use acronyms or short forms in names.
  53. Don't write functions that are much longer than the number of lines visible in the editing window.
  54. Do write short file and class header comments, and include reference links to design support material.
  55. Do indicate known limitations with //FIXME: and //TODO: comments
  56. Do use intellisense comments in headers to document public class interface.
  57. Do use intellisense comments in source files to document encapsulated functions and data.
  58. Do design and implement so that business logic can be rehosted at reasonable cost.
  59. Do design and implement so that support logic can be re-used on other projects.
  60. Don't get hung up on perfect portability if this isn't a recognized (budgetted) pre-requisite.
  61. Do start test driven development immediately.
  62. Don't extend feature content without adding unit tests to cover new features.
  63. Do monitor test coverage regularly, and set goals to continuously improve.
  64. Don't allow technical debt to accumulate.
  65. Do select a unit test framework that will remain viable for the anticipated life-cycle of the solution.
  66. Do accommodate your answer to cross-cutting issues in unit tests.
  67. Do use utf8-everywhere coding paradigm in unit tests.
  68. Do consider unit test support libraries, and building a mock-up framework to assist stateful unit testing.
  69. Do identify limit and isolate stateful behavior, and favour stateless design for classes.
  70. Do use PIMPL to localize legacy code styles and use of legacy and system API's.
  71. Do rigorously apply UTF-8 everywhere, STL GSL and ISO C++ in (.hpp) public interfaces for PIMPL classes.
  72. Do use precompiled headers and #pragma once.
  73. Do explicitly include the headers used by headers (.hpp) in the headers themselves.
  74. Do explicitly include the headers used by source (.cpp) in the source files themselves.
  75. Don't include platform headers in project headers (.hpp). Restrict platform header use to PIMPL .cpp files.
  76. Do peer review to confirm asppropriate rule-of-five and rule-of-zero design choices.
  77. Do apply C++ Core guidance using static analysers frequently, or at build time.
  78. Do use RAII as primary strategy for avoiding memory leaks.
  79. Don't rely on RAII techniques to restore system state. (consider also need for signal handlers).
  80. Do exploit RAII by favouring structured exception handling and throwing std::exceptions when unmanaged errors arise.
  81. Do consider adding locus/context to exceptions (see error::context) to accelerate time to fix.
  82. Do favour smart pointers and spans, over use of raw pointers.
  83. Do make good use of auto type derivation.
  84. Don't use explicit gsl::as_span on a vector when an automatic typecast is implicit.
  85. Do take time to study STL features and use patterns, with emphasis on containers and algorithms.
  86. Do take time to study and understand templates, so you can read and follow STL implementations.
  87. Do use precompiled header as a place to disable C++ Core false positives and unwanted warnings.
  88. Do apply a logging strategy that is not locked to a specific logger implementation.
  89. Do consider all the dos and don'ts from "Effective Modern C++".
  90. Do keep records and make regular (e.g. quarterly quality reports) giving trends in test coverage, peer review results and bugs found.
  91. Do regularly assess quality reports and use them to attend to any systematic process weakeness they indicate.
  92. Do occasionally assess quality reports to reconsider value of sub-classification of issues to identify common causes.
  93. Do consider check-in time as a compliance opportunity. Write-down and enforce your check-in process that uses a derivative of this quality guidance in the way that you find most acceptable and effective.
  94. Do consider periodic quality report dates as a compliance opportunity. Assess overall development process effectiveness critically at these points, to promote responsiveness in continuous improvement.
  95. Do configure warning levels.
  96. Don't let builds report warnings (Fix code!)
  97. Do use #pragmas to explictly disable specific instances of particular warnings (after assessment, as last resort).
  98. Do enable code analysis on build.
  99. Do strongly favour passing input parameters as const reference.