How can you identify legal C without understanding undefined behavior? Or rather, what is the list of UB that nay professional C developer should be expected to know?
> If someone has some examples that a reasonable person would write, specifically examples that look like the simplest way to do something, then I’d love to hear them.
Basically all OOP-style C. For instance, the Windows macro
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(ULONG_PTR)(&((type *)0)->field)))
The Linux kernel is also an excellent source of these.Also, serialization/deserialization libraries are an excellent source for UB. And huge amounts of code depends on UB by using unsigned char arrays for storage of other types.
Furthermore, in practice, C code assumes most of the following:
- null pointers are represented as 0, e.g. if(ptr).
- pointer provenance does not exist
- char and unsigned char are 8-bit bytes
- two's-complement arithmetic
- page-based memory protection
- no types have trap representations
- the values of base types, besides floating point, do not have multiple representations.
- etc