But yes, some code with UB which works for now might break. But that’s true whenever you upgrade your C compiler or use optimizations, so for correctness you shouldn’t do either! People working on certified embedded software have known that for long.
The real problem is that C users have been lied to. They’ve been taught the lie that C pointers are just addresses, that memory is an array of bytes, that relying on this lie is robust, and that this combination is fast. But this combination is impossible.
EDIT: officially some behavior was implementation-defined, but implementations made it undefined anyway — either officially or via bugs; links in subthread.
>The real problem is that C users have been lied to.
I think the real problem is that the committee is creating a language that the users neither need nor understand. The users want a language where pointers are, in fact, just address.
And pointers weren’t addresses before either. My favorite example of “pointers aren’t addresses” is this kind of code:
int a[…]; int b[…]; /* … */ a[i] = 0; b[j] = 1; return a[i];
Ignoring this discussion for a moment, wouldn’t you expect `return a[i];` to optimize to `return 0;` here? After all, `a` and `b` are disjoint arrays! I’m sure many would be disappointed if the compiler did not do that optimization, right?
If I wanted language with clever optimisations I'd go for something way higher level like lisp, haskell. Most optimisations are often only useful to make sure you can program generically without a headache. Optimizing code generated by macros or monomorphisation/type specialisation/template instantiation/however you call it is really useful. Is it worth it otherwise? For me the difference between gcc -O1 and -O3 suggest this is not worth it in the domain where c is typically used.
Mainly because it lets you use systems with type-safe pointers (some acronyms are PAC, BTI, CHERI) - the regular "concrete semantics" aka "whatever current pointers let you get away with" has a lot of issues! But also because compiling with extra security is not popular if it causes performance regressions.
[...]
> But also because compiling with extra security is not popular if it causes performance regressions.
Yes. So while UB could theoretically be (in some cases) good for security, in practice it is absolutely not, because no tooling exists to introduce runtime checks light enough to be used in production. So UBs can and do reveal and/or amplify latent bugs, or even introduce new ones if new UB are introduced in new specifications.
And that's ok. There are tools for that at the reach of those who place a premium on those requirements.
For those who favour interoperability, simpler mental models, efficiency, and more importantly a tool with a proved track record, there's C.
And there are plenty of reasons why C is the de facto standard in spite of all alternatives.
For instance, GCC sometimes tracks pointer provenance through integers; this proposed change will make that clearly illegal.
>Ptr2int casts were never legal
Citation on this? The existence of uintptr_t seems to say otherwise.
>That ship already sailed
In principle, I see no reason preventing future versions of the standard from defining previously-undefined behavior. That said, you are probably right in a realpolitik sense.
From N2176, Sec. 6.3.2.3, p. 5-6: > An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
> Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.
AFAICT, that doesn’t even guarantee that a roundtrip is the identity — which C++ mandates and is still the case: http://eel.is/c++draft/expr.reinterpret.cast#5
EDIT: GCC does have those restrictions in place already: https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gcc/Arrays-and-poi...
and since a while (earliest relevant docs I could find easily): https://gcc.gnu.org/onlinedocs/gcc-3.1.1/gcc/Arrays-and-poin...
EDIT2: LLVM doesn’t document this “implementation-defined behavior” (or most others), even if docs are explicitly required by the standard; but it does use pointer provenance in practice already, but not in a way that’s easy to explain.
None of these need speed. They need reliability and maintainability. The standards committee is prying the language out of the hands of these people. Because they need, using your words, "interoperability, simpler mental models," which is sabotaged by efforts like this one.
That would only explain why C featured as one of the choices on the table.
But from that point on, people like you and me made conscious decisions based on their requirements and preferences, and C frequently was everyone's top choice.
Quality is surely not the common factor to all those top choices, rather being the platform owners, with all that it entails to the surrounding ecosystem.
No, not really, and frankly this feels like a disingenuous comparison done in bad faith. I'm sure you know that, unlike C, javascript is pretty much the only option on the table if your goal is to produce anything remotely resembling production code. Also, as you certainly are aware, that's far from the case with C. In fact, you should certainly be aware that one of the most popular compiler toolkits there is, and one which has been the de facto standard for a few decades now, offers C only as a front-end, on par with languages such as Ada, which already was around for close to a decade before C's first international standard was published.
Thus, you'll need to come up with an explanation of why people repeatedly pick C over well established languages explicitly designed to meet he requirements you favour, and one which is already around for four decades, and is already standard and widely available and enjoys some adoption in some fields. But in spite of it everyone still picks C over it.
The other being C++, which happens to be for better or worse, almost copy-paste compatible with C89, also also a UNIX child born a couple of offices down the corridor.
Interesting that you pick Ada, given how outrageous the compilers used to cost, versus the freebie C compiler that already came on the box, and cleverly washout the complaints on the FOOS community that won't touch GNAT due to licensing FUD.
Who is on bad faith here?