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;
// ...
}
}