Edit

Share via


Warning C26448

Consider using gsl::finally if final action is intended (gsl.util)

C++ Core Guidelines: GSL.util: Utilities

The Guidelines Support Library provides a convenient utility to implement the final action concept. Since the C++ language doesn't support try-finally constructs, it became common to implement custom cleanup types that would invoke arbitrary actions on destruction. The gsl::finally utility is implemented in this way and provides a more uniform way to perform final actions across a code base.

There are also cases where final actions are performed in an old-fashioned C-style way by using goto statements (which is discouraged by C26438 NO_GOTO). It's hard to detect the exact intention in code that heavily uses goto, but some heuristics can help to find better candidates for cleanup.

Remarks

  • This rule is lightweight and uses label names to guess about opportunities to use final action objects.
  • Label names that can raise a warning contain words like "end", "final", "clean", and so on.
  • Warnings appear at the goto statements. You may see verbose output on some occasions, but the output may help in prioritizing code, depending on its complexity.
  • This rule always goes in pair with C26438 NO_GOTO. Depending on the priorities, one of these rules can be disabled.

Code analysis name: USE_GSL_FINALLY

Example

Cleanup with multiple goto statements:

void poll(connection_info info) { connection c = {}; if (!c.open(info)) return; while (c.wait()) { connection::header h{}; connection::signature s{}; if (!c.read_header(h)) goto end; // C26448 and C26438 if (!c.read_signature(s)) goto end; // C26448 and C26438 // ... } end: c.close(); } 

Cleanup with multiple goto statements replaced by gsl::finally:

void poll(connection_info info) { connection c = {}; if (!c.open(info)) return; auto end = gsl::finally([&c] { c.close(); }); while (c.wait()) { connection::header h{}; connection::signature s{}; if (!c.read_header(h)) return; if (!c.read_signature(s)) return; // ... } }