On 12/01/2024 00:15, Anthony Cuozzo wrote:
> On 1/11/24 07:43, David Brown wrote:
>> On 11/01/2024 05:15, Anthony Cuozzo wrote:
>>> The only tool I use regularly for identifying instances of undefined
>>> behavior is the semantics compiler "kcc" from RV-Match.
>>>
>>> Are there any other tools out there besides what ships with e.g., GCC
>>> & Clang?
>>>
>>
>> Both gcc and clang have "sanitizers". You compile the code with the
>> appropriate options, and the code is augmented with checks for
>> different kinds of UB, detected at run-time. gcc and clang have many
>> of these in common, and some that are only implemented in one of
>> them. Some sanitizers can have significant impact on code speed,
>> others do not. You will want to try things with different flags to see
>> what works best for you.
>>
>> <
https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fsanitize_003dundefined>
>>
>> <
https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html>
>>
>>
>> Both gcc and clang can also do a great deal of static error checking
>> which can find some kinds of UB before running the code. And there
>> are other tools such as clang-tidy, and third-party linters and
>> checkers, that can help. (Some are quite expensive.)
>>
>>
>
> I suppose I was/am looking for static analysis tools which focus on UB,
> but now that I've given it more thought I realize that only a subset of
> UB can be detected at compile time.
That is absolutely correct. In fact, most UB can only be detected at
run time. Static analysis (in a compiler, or dedicated tools) can
usually only see some kinds of /potential/ UB. For example, if you
write "int foo(void) { return 1 / 0; }", that is not UB in itself - it
is only UB if your program calls "foo". And usually the compiler isn't
able to determine what code will actually be called when you run the
program, unless it can trace the execution unconditionally from main().
But it is, IMHO, a good idea to find as many of your codes bugs as
possible using static checking - it's the easiest and cheapest time to
do it. gcc and clang both have quite sophisticated warnings and static
analysis features (with steadily more for each new compiler release),
and clang also has some stand-alone tools for the job. There are also
dedicated tools for particular use-cases (such as tools for checking
Linux kernel code for certain kinds of problems). And there are quite a
number of commercial tools that do very sophisticated static error
checking, if your budget stretches to buying them.
>
> Semi-related: Do you know if there's a resource which breaks down UB per
> standard? I'd like to see how things have changed over time.
>
Each C standard version has an Annex that lists the explicit UB
described in the standard - but remember that things that have no
standards-defined behaviour are also UB in C (though a compiler may
choose to define them).