Skip to content

Document argument evaluation cost and add generated-stub CI check - #2

Merged
deblasis merged 2 commits into
mainfrom
docs/zero-overhead-caveat-and-gen-check
May 30, 2026
Merged

Document argument evaluation cost and add generated-stub CI check#2
deblasis merged 2 commits into
mainfrom
docs/zero-overhead-caveat-and-gen-check

Conversation

@deblasis

Copy link
Copy Markdown
Owner

What

Two small things that came out of a closer read of the zero-overhead claim.

1. Document that arguments are still evaluated in release builds

The "zero overhead" guarantee is real for the assertion machinery: in a release build the calls inline away to nothing and there are no allocations. I confirmed this by disassembling a release binary, Should(ptr).NotBeNil() and Should(n).BeGreaterThan(0) compile to zero instructions.

What is not removed is the expression you pass in. Go evaluates function arguments before the call, and a no-op cannot un-evaluate them. This differs from a C-style assert() macro, which the preprocessor deletes entirely under NDEBUG. So a computed or side-effecting condition still runs in production:

bumert.Assertf(expensiveCheck(), "must hold") // expensiveCheck() still runs in release

Verified empirically: with this line in a release build the side effect still fires, and the disassembly shows the only instruction left on that line is the CALL to the argument function.

The README now spells this out and points readers at TrueFn, which defers the work behind a closure that is never called in release builds. Also verified: the TrueFn body runs only under -tags debug.

2. Add a CI guard for the generated release stubs

bumert_release.go is generated from bumert_debug.go. If someone adds a debug assertion and forgets to run make generate, the release build can reference a missing stub. CI already checks formatting and tidiness but not stub drift.

Added a check-generate Makefile target and a Check Generated Stubs CI step that runs make generate and fails if bumert_release.go changed.

Changes

  • README.md: new section explaining the check-is-free-but-argument-is-not distinction, with the TrueFn workaround.
  • Makefile: new check-generate target.
  • .github/workflows/ci.yml: new step running make check-generate before the test jobs.

No functional changes to the library.

deblasis added 2 commits May 30, 2026 03:47
Document that the zero-overhead guarantee applies to the assertion
machinery, not to the expression passed in. Go evaluates arguments
before the no-op call, so a computed or side-effecting condition still
runs in release builds. Point users at TrueFn to defer expensive work.

Add a check-generate Makefile target and a CI step so the build fails
if bumert_release.go is out of date with respect to the debug source.
Pass the value being asserted to Should() and reference it inside the
closure, instead of the confusing Should(nil) idiom.
@deblasis
deblasis merged commit 45f493b into main May 30, 2026
1 check passed
@deblasis
deblasis deleted the docs/zero-overhead-caveat-and-gen-check branch May 30, 2026 01:52
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.

1 participant