4 ms·
A core part of the problem of UB in C and C++, is that it is gratuitously over applied. Mercifully the article calls out the BS argument of "old hardware" just
by olliej 3y ago
A core part of the problem of UB in C and C++, is that it is gratuitously over applied.
Mercifully the article calls out the BS argument of "old hardware" justifying UB. It is simply a false argument. The overwhelming majority of UB in C and C++ should be either implementation defined or unspecified behaviour. Security vulnerabilities due to overflow or null dereferences being UB should never have been possible because there are no platforms in which those operations are not defined (some trap, some wrap, some go to infinity), but that is all under the banner of implementation defined behavior. Labelling these things as UB is _solely_ to allow performance optimizations in narrow cases, at the cost of safety in all cases.
In committee meetings I've been in recently the new refrain I'm hearing/reading that has replaced "we need to support various hardware" is an even more stupid argument: if we make it so that these aren't UB then people will rely on the common behavior and write code that is incorrect on platforms that behave differently. e.g. instead of software that is always wrong on one platform, you make software that is semi-randomly wrong on all platforms (because whether or not a compiler removes UB in one case is dependent on compiler version, flags, inlining, etc and if any of those change then suddenly the same code you had yesterday has a security bug when shipped).
- bluGill 3y agoUb is a bug. We can define what happens, but your code is still wrong if it gets there. Leaving it undefined mean the optimizer can make useful optimizations sith no harm as your code should be useful anyway.
- olliej 3y agoIn what sense? C and C++ aren’t memory safe, so the specification has to say something about what happens if you’re dereferencing an invalid pointer (random value, out of bounds, frees pointer, etc). That’s what UB exists for: there’s no behaviour we can actually define for some operations.
- ack_complete 3y agoNot always. [fs.race.behavior] makes it undefined behavior to use the C++ filesystem library in a way that introduces a race on the filesystem, including with _other processes_: https://eel.is/c++draft/fs.race.behavior https://eel.is/c++draft/fs.race.behavior I'm not sure how it is possible for a program to avoid this.
- lifthrasiir 3y agoMany enough UBs are just a mismatch between the specification and programmer intents. Strict aliasing is a good example: why should aliasing be only allowed through `union` and otherwise UB? Only because it's easier to analyze and optimize. The specification could have instead defined any pair of explicitly aliasing types should be considered aliased, but then the possible optimization will be severely limited (for example, aliasing in one translation unit can inhibit an optimization in other units).