This would prevent the last bug (!ua()) as the control flow sensitive analysis can reason about both branches: that it is invalid to deref ua within the block. The dynamic check misses the bug because the branch is never taken for the given inputs.
I am fairly confident that the clang-tidy pass is simpler and more precise in most cases than the hand-rolled implementation. (That said the static check may not be able to reason about mutation well.)
If you need to pass an error in the failure case, you can use std::expected (available in C++23). clang-tidy has an open bug about supporting a similar check for std::expected: https://github.com/llvm/llvm-project/issues/135045
Funny if only marginally related fact: even though neither the C++11 syntax
if (int x = foo(); x) { ... }
nor the C++98 syntax
if (int x = foo()) { ... }
is supported in C99, it still introduces the rule that the entire if statement is a scope (which it wasn’t in C89). So as a party trick, here’s a way to check for C99 without using the preprocessor:
Pretty sure that means that tcc at least believes it is a C99 (or later) compiler; if it conformed to an earlier spec it (probably?) would have considered the inner `enum { C99 = 0 }` definition to be still in scope, and the return value would be 0.
If you are willing to return std::optional, clang-tidy has a (static) control flow sensitive check that enforces you check to see the value is valid before unwrapping. https://clang.llvm.org/extra/clang-tidy/checks/bugprone/unch...
This would prevent the last bug (!ua()) as the control flow sensitive analysis can reason about both branches: that it is invalid to deref ua within the block. The dynamic check misses the bug because the branch is never taken for the given inputs.
I am fairly confident that the clang-tidy pass is simpler and more precise in most cases than the hand-rolled implementation. (That said the static check may not be able to reason about mutation well.)
If you need to pass an error in the failure case, you can use std::expected (available in C++23). clang-tidy has an open bug about supporting a similar check for std::expected: https://github.com/llvm/llvm-project/issues/135045
Funny if only marginally related fact: even though neither the C++11 syntax
nor the C++98 syntax is supported in C99, it still introduces the rule that the entire if statement is a scope (which it wasn’t in C89). So as a party trick, here’s a way to check for C99 without using the preprocessor: I make no promises about the behaviour of this code on insufficiently anal compilers like TCC.> I make no promises about the behaviour of this code on insufficiently anal compilers like TCC.
But tcc isn't a C++ compiler at all?
tcc version 0.9.28rc returns "1", whatever that means.
Pretty sure that means that tcc at least believes it is a C99 (or later) compiler; if it conformed to an earlier spec it (probably?) would have considered the inner `enum { C99 = 0 }` definition to be still in scope, and the return value would be 0.
I think.