Null-safe Free Wrappers

When a free/cleanup API may receive NULL (or an invalid handle), don’t rely on ad-hoc checks at call sites. Instead, define a NULL-safe wrapper/helper that:

copy reviewer prompt

Prompt

Reviewer Prompt

When a free/cleanup API may receive NULL (or an invalid handle), don’t rely on ad-hoc checks at call sites. Instead, define a NULL-safe wrapper/helper that:

  • No-ops when the argument is NULL (mirrors free(NULL) semantics).
  • Avoids double-evaluation (store the argument in a temporary).
  • Preserves compile-time type checking (use a correctly typed temporary; avoid unnecessary casts).
  • Is safe to use across versions when needed (e.g., macro wrapper vs direct symbol).
  • Also guard cleanup operations (e.g., close) to run only when the handle was actually acquired.

Example pattern (C):

/* NULL-safe wrapper: evaluates arg once, type-checked, no-op on NULL */
#define Module_FreeStringSafe(ctx, str) \
    do { \
        RedisModuleString *_ms = (str); \
        if (_ms) RedisModule_FreeString(ctx, _ms); \
    } while (0)

Example guard (Tcl):

if {$fd ne {}} {
    catch {close $fd}
}

Apply this rule consistently to any code path that frees/finalizes memory or resources that might be absent due to conditional logic or partial failures.

Source discussions