Simple MISRA C with all warnings on is already close to language with strict type checking. C compilers give you a choice, use it. If you are programming for money, good static analyzer makes it possible to write safety critical code.
Simple MISRA C with all warnings on is already close to language with strict type checking. C compilers give you a choice, use it. If you are programming for money, good static analyzer makes it possible to write safety critical code.
"Although the first edition of K&R described most of the rules that brought C's type structure to its present form, many programs written in the older, more relaxed style persisted, and so did compilers that tolerated it. To encourage people to pay more attention to the official language rules, to detect legal but suspicious constructions, and to help find interface mismatches undetectable with simple mechanisms for separate compilation, Steve Johnson adapted his pcc compiler to produce lint [Johnson 79b], which scanned a set of files and remarked on dubious constructions."
Dennis M. Ritchie -- https://www.bell-labs.com/usr/dmr/www/chist.html
Unfortunately too many think they know better than the language authors themselves.
Would it be possible to have a standard, where undefined behavior is just a compile error? What would we lose - apart from legacy compatibility?
No [if you're aiming for something in the same vein as C]. Undefined behavior is ultimately an inherently dynamic property--certain values could make a statement execute undefined behavior, and consequently, virtually every statement could potentially cause undefined behavior. Note that this remains true even in languages like Rust: Rust has loads of undefined behavior, but you do have to wrap code in unsafe blocks to potentially cause undefined behavior.
> What would we lose - apart from legacy compatibility?
In particular, it is clear at this point that if you want to permit converting integers to pointers, you will either have to live with undefined behavior (via pointer provenance) or forgo basically all optimization whatsoever.
UB started as means to not kick out computer architectures that would otherwise not be able to be targeted by fully compliant ISO C compilers.
Given that C prefers to be a kind of portable macro assembler than care about security, it was only a matter of time until those escape hatches started to be taken advantage for optimizations.
Same applies to other languages, however since their communities tend to prefer security before ultimate performance, some optimization paths are not considered as that would hurt their safety goals.
In what concerns C, C++ and Objective-C, dropping UB optimizations would mean going back to the 1990's in terms of code quality.
int foo(int x, int y) { return x+y; }
compile? After all, this function can be called in a way that causes UB.Unless your program can prove, that the function is only ever called with arguments that don't hit UB.
(This is the case in e.g. C#.)