Challenge 3: Static vs. Dynamic Analysis, and Why Rust's Default Analysis Is a Stronger Guarantee — Possible Solution ==================================================================== The KEY DIFFERENCE, per the chapter: static analysis tools (clang-tidy, cppcheck) examine SOURCE CODE without ever running the program at all -- they reason about the code's structure and possible states abstractly. The dynamic tools covered earlier (valgrind, ASan, UBSan, gdb) all require the program to actually EXECUTE, and can only observe whatever specific behavior happens during that particular run -- exactly the limitation Challenge 2 explored, where an un-exercised code path is invisible to every one of them. Static analysis, by contrast, can in principle examine EVERY code path in the source, whether or not any particular test run happens to exercise it -- though it trades this breadth for being generally less precise about runtime specifics (actual memory addresses, actual thread interleavings) that only a dynamic tool can observe directly. Why Rust's compiler performing similar analysis by default is a MEANINGFULLY DIFFERENT guarantee than a C team choosing to run a static analyzer: in C, static analysis is described in the chapter as "a separate, optional tool a team has to deliberately choose to run" -- nothing about GCC or Clang's own core compilation process requires it, enforces it, or blocks a build if it's skipped. A team can compile and ship C code having never run clang-tidy or cppcheck a single time, and the compiler itself raises no objection. Rust's borrow checking and type checking, per the chapter, are "a mandatory part of compilation" -- there is no way to produce a working Rust binary at all without that analysis having already passed. This isn't a difference in how THOROUGH each analysis is in isolation -- it's a difference in whether the analysis is GUARANTEED to have happened at all for any given compiled program. A C codebase's safety-relevant guarantees depend on a team's own discipline choosing to opt in to extra tooling; a Rust codebase's equivalent guarantees are enforced unconditionally, for every single build, by the language's own toolchain. WHY THIS WORKS AS AN ANSWER ------------------------------ This states the static-vs-dynamic distinction precisely (examines source without running vs. requires actual execution), correctly notes static analysis's breadth/precision tradeoff versus dynamic tools, and identifies the real difference in Rust's default analysis as being about GUARANTEED ENFORCEMENT (mandatory, unconditional) rather than merely "Rust's tools are better," which is the actual distinction the chapter draws.