4 ms·
Does Carbon have any undefined behavior? Some of the wording in their goals document suggests that they do/will, but it isn't clear to me.
by jjnoakes 2y ago
Does Carbon have any undefined behavior? Some of the wording in their goals document suggests that they do/will, but it isn't clear to me.
- gumby 2y agoUnless you solve the halting problem, every language has undefined behavior.
- tialaramex 2y agoNope. A language which has semantic requirements and isn't willing to reject programs for which it has been unable to determine whether they meet the requirements, will have these cases by Rice's Theorem. This is why C++ is a complete disaster. C++ specifically does not allow the compiler to reject such programs. You can defuse this like (safe) Rust by just writing conservative checking. You will reject some programs you would like to have successfully compiled, but that's actually OK, programmers who hate it are inspired to improve the checking, that's what Rust's "Non-Lexical Lifetimes" - mentioned by Sean, are about. Even more radically, you can be a Special Purpose language and just only allow a relatively small subset of possible programs, all of which you know are correct, that's why WUFFS gets to emit indexing with no runtime bounds miss checks - it did all the bounds checks at compile time, all source where that wouldn't be possible isn't legal WUFFS code.
- mgaunard 2y agoThat is incorrect. A C++ compiler is perfectly allowed to reject any program that contains undefined behaviour. It's just not required to do so.
- leni536 2y agoIt's allowed to reject programs that will evaluate an undefined operation on every possible execution. This is pretty much impossible, so no compiler even attempts this.
- mgaunard 2y agoIt can replace any path with undefined behaviour to one that does std::abort.
- tialaramex 2y agoThat would be easy, the problem is that Rice's Theorem tells us the compiler definitionally cannot be sure whether every possible source code represents a valid program if it has any non-trivial semantic requirements (C++, like Rust, has a whole lot of such requirements). So while "What should we do when we're sure it's not a valid program?" is easy and so it's very silly that some C++ compilers will compile that anyway, it's not enough, you also need to decide "What should we do when we're not sure?" and there the ISO document provides a firm answer, which all the compiler vendors follow - press on anyway, too bad. "Ill-formed - No Diagnostic Required" is how the ISO document describes this situation. The diagnostic isn't required because it's technically impossible to guarantee. You might insist that "Not sure" can't happen. Unfortunately the reason it's called Rice's Theorem is that a guy named Henry Rice got himself a Maths PhD proving this in 1951.
- gumby 2y agoI suppose you can make that assertion by moving the goalposts. But Rice's theorem specifically addresses such behavior: all turing machines are inherently undecidable for all but trivial cases. You can well argue that Rust may be better than C++ in some dimension, just as others can argue that those qualities have an unreasonable or intractable cost (note that about 20% of all crates resort to `unsafe`). But your blanket assertion is not even supported by the reference you made. Also the user is free to tell a C++ compiler to reject programs that use many sorts of undefined behavior, though indeed nobody would claim that any current compiler can identify all such cases. But Rice's theorem says that no Rust compiler could either.
- mike_hock 2y agoYes, but it seems that we can't satisfy all reasonable real-world use cases this way, or else Rust wouldn't have the "unsafe" escape hatch that's actually used by real code.
- School-Cotton 2y agoThat’s not true. The halting problem / Rice’s theorem only mean that the behavior can’t be statically determined by the compiler, not that it’s undefined.
- Yoric 2y agoC++ has a specific definition of UB. Most languages don't suffer from it, regardless of halting problem.
- Asooka 2y agoNo? The CPU doesn't have undefined behaviour, thus any code running on it doesn't have undefined behaviour either. There are certain operations whose result is not defined in certain states, I think on Intel some SSE operations had undefined results, but even then the same order of operations will lead to the same result. C/C++ compilers generally let you turn off almost all possible undefined behaviour assumptions. I think the only one you can't turn off is the assumption that a pointer to an object is properly aligned, which is understandable - if every pointer had to be checked for alignment before every access, it would ruin performance. In general I would be much happier if I could assert to the compiler that my data fits certain parameters and it would optimise based on these explicit assertions rather than on implicit assumptions (undefined behaviour). Those assertions could be turned off in the final build if we determine they actually impact performance, but I expect I'd be able to keep them on all the time.
- fluoridation 2y agoCPUs do have undefined behavior.
- gumby 2y ago> The CPU doesn't have undefined behaviour, thus any code running on it doesn't have undefined behaviour either. Have you read Rice’s theorem? Every nontrivial program on a Turing machine (which has only defined behavior) is undecidable.
- summerlight 2y agoMy understanding is that if you want a high level of semantic compatibility with C++, a certain degree of UB is quite hard to avoid. But at least unlike C++, they prefer not to leave 100s of different possibilities on the table.