Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add defensive programming resources #36

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jeremy-rifkin
Copy link

This PR adds links to libassert (shameless plug, I'm the author), and Bloomberg bsls_assert as resources for defensive programming

@MattPD
Copy link
Owner

MattPD commented Apr 29, 2024

Thank you for the patience! I definitely want assertions in cpplinks (I'm a big fan of assert-early-assert-often, as in https://llvm.org/docs/CodingStandards.html#assert-liberally) and I think the library is great, too, so a perfect fit.

What I've been thinking of is where to put these exactly (category-wise). I'm still not quite sure, so perhaps you can help me out, if you feel like (or it's going to be me (over-)thinking out loud otherwise).

Context: I think there's value in having good categorization, so as to avoid growing into one big "awesome list" (subjectively I consider this an anti-pattern: For practical, selfish purposes I also want to be able to use cpplinks myself to quickly find what I need).

This is the background that resulted in debugging.tracing being separate from debugging, testing.fuzzing being separate from testing, or compilers.correctness being separate from compilers.

In the same vein, I'm wondering whether asserts fit into debugging directly (in a defensive_programming section, which is also what I'm not sure about), elsewhere, or whether these deserve a distinct category.

Some thoughts and open questions:

  • there's an overlap with some use cases for debugging and testing--or, arguably, broader (WIP) design
  • would anything related to static_assert be still a good fit in that category (as in: if you were looking for resources on static_assert would you look under debugging?)--or warrant another one (which)? correctness (thinking of A. Turing (1949) "Checking a large routine")? contracts? design.correctness?
  • simply assertions may be a better name (whether as a category or a section) as whether defensive_programming itself is a good choice depends on the accepted meaning, with some differences and sources putting these in contrast, https://en.wikipedia.org/wiki/Offensive_programming
    • B. Meyer, “Applying design by contract,” IEEE Computer, vol. 25, Oct. 1992, https://se.inf.ethz.ch/~meyer/publications/computer/contract.pdf:
      • "This principle is the exact opposite of the idea of defensive programming, since it directs programmers to avoid redundant tests. Such an approach is possible and fruitful because the use of assertions encourageswriting software to spell out the consistency conditions that could go wrong at runtime. Then instead of checking blindly, as with defensive programming, you can use clearly defined contracts that assign the responsibility for each consistency condition to one of the parties. If the contract is precise and explicit, there is no need for redundant checks."
      • "In the absence of assertions, defensive programming may be the only reasonable approach. But with techniques for defining precisely each party’s responsibility, as provided by assertions, such redundancy (so harmful to the consistency and simplicity of the structure) is not needed."
    • "DbC is, in a way, the opposite of defensive programming, a method which recommends to protect every software module by as many checks as possible." - Herbert Toth: “On theory and practice of Assertion Based Software
      Development”, in Journal of Object Technology, vol. 4, no. 2, March-April 2005, https://www.jot.fm/issues/issue_2005_03/article2.pdf
    • "Assertions are of little use in this situation. Defensive programming or programming by contract [6] are
      better suited to handle this task." - C.A.R. Hoare, "Assertions: a personal perspective" https://www.state-machine.com/doc/Hoare03.pdf
  • if defensive_programming, then would defensive_programming fit as a part of, say, design.defensive_programming?
    https://github.com/CppCon/CppCon2014/blob/master/Presentations/Defensive%20Programming%20Done%20Right/Defensive%20Programming%20Done%20Right%20-%20John%20Lakos%20-%20CppCon%202014.pdf
  • correctness#assertions may be perhaps a better fit as debugging doesn't seem to (directly?) cover use cases such as these (from https://blog.regehr.org/archives/1091):
    • "The Linux kernel generally wants to keep going no matter what, but even so it contains more than 11,000 uses of the BUG_ON() macro, which is basically an assertion — on failure it prints a message and then triggers a kernel panic without flushing dirty buffers. The idea, I assume, is that we’d rather lose some recently-produced data than risk flushing corrupted data to stable storage. Compilers such as GCC and LLVM ship with assertions enabled, making the compiler more likely to die and less likely to emit incorrect object code."
    • "Assertions are Boolean formulas placed in program text at places where their evaluation will always be true. If the assertions are strong enough, they express everything that the programmers on either side of an interface need to know about the program on the other side, even before the code is written. Indeed, assertions can serve as the basis of a formal proof of the correctness of a complete program." - C.A.R. Hoare, "Assertions: a personal perspective"
    • although either one has some overlap (Herb Sutter's "Assumptions" paper, https://wg21.link/p2064)
      • "If all assertions are true, then increases confidence that the program is correct"
      • "Assert is a safe debugging aid that should be used pervasively by all programmers"

(On a side note, perhaps error_handling would fit under correctness.error_handling?; One thing I'm sure of is that I agree with https://blog.regehr.org/archives/1091 that asserts themselves do not belong in the error_handling category. This does however make me hesitate to just create top-level assertions.md if there's a broader category that would be a better fit. FWIW, in retrospect I think using top-level atomics.lockfree.memory_model.md directly was a mistake--and concurrency would have been a better choice.)

Let me know if you have any thoughts on these; thanks!

@jeremy-rifkin
Copy link
Author

Hi Matt! Thank you for the context on the organization of the project. I'm happy to opine, however, you have definitely given this much more thought than I have. (And TIL about offensive programming)

The main concepts to me seem to be defensive programming / "assert early assert often" philosophy, design by contract, and error handling. To me these fit very comfortably under a correctness (or design.correctness) category.

static_assert is tricky to place. To me many uses of static_assert seem comparable to contracts, such as static asserting that a struct is a certain size or satisfies certain concepts, and I wonder if it would fit under a design by contract sub-category.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants