4 ms·
Whatever happens for the other UB remains bounded memory safely in Fil-C. (according to a definition of memory safety that excludes protection of subobject boun
by uecker 20d ago
Whatever happens for the other UB remains bounded memory safely in Fil-C. (according to a definition of memory safety that excludes protection of subobject bounds, but Rust also redefines memory safety to what the Rust compiler can do, e.g. excludes memory leaks).
- mirashii 20d agoI'm not so sure you can make such a strong statement about what happens when UB is invoked. The presence of UB allows the compiler to make all kinds of weird assumptions, and it seems very unlikely that there exists no series of allowable transforms that results in a pointer capabilities check being elided or similar.
- tialaramex 20d agoPresumably Martin intends the usual caveat that this is subject to bugs. So, "there might be a bug in the compiler" isn't interesting. There are bugs in LLVM, bugs in Rust's trait resolution, bugs in Javascript implementations, obviously code has bugs and that's generally not very interesting - we can fix bugs. Are you claiming that there must be such transforms or only that it is likely that bugs exist which isn't interesting.
- mirashii 20d agoNeither. I'm claiming that UB allows a transform that violates or ignores the additional guards put in place by Fil-C, and by the definition of UB that is not a bug in the compiler, as any behavior is allowable. To assert that something specific always happens under UB is counter to the definition of UB. Fil-C carefully defines away UB for some operations, but to make full guarantee of safety, even by their definition and modulo bugs, I believe it necessary to fully remove UB.
- tialaramex 20d agoMaybe it was unclear that Fil-C is a compiler. So the thing doing those transforms you're worried about is Fil-C. Fil-C gets to look at some code which has UB if variable z is 9 and go "OK, lets check whether z is 9, and if so...". The result, of course, is much, much slower than executables from a typical modern C compiler, but since "It always does X" is in fact a permitted implementation of "Undefined Behaviour" this is a compliant C implementation, at least in most observable respects.
- tialaramex 20d agoLeaking isn't unsafe. Even if you have a linear type system, and so you can't leak in this useless technical sense, it makes no practical difference, the end user doesn't care that your program which gradually bloats by 1GB per hour until it blows up doesn't technically "leak" memory because it was just caching some data with no limits, whereas my program which grows by 800MB per hour and thus blows up slightly less often does technically "leak" memory because it didn't keep the references needed to free that data. To the end user these programs are both leaky garbage.
- uecker 19d agoThis depends on the definition. Rust originally included leaks in their definition of unsafe and later changed the definition when they found out that they can not reliably prevent leaks. Leaks could reasonably be considered unsafe as they can cause a program to crash due to resource exhausting, even where the actually used memory is limited. If you do not consider leaks as part of the problem, there is a trivial way to avoid use-after-free and double-free: Simply never free any memory or only at the very end. (Which in some scenarios is exactly what people do.) The later would fulfill your definition of "holding references to be able to free them".
- tialaramex 19d ago> Leaks could reasonably be considered unsafe as they can cause a program to crash due to resource exhausting, even where the actually used memory is limited. You can make this claim about any resource, there's no reason to single out memory here. You can run out of file descriptors, inodes, connections to a remote database, disk space, anything - including CPU time. And notice that it wasn't the leak that you've now said was unsafe, it was the use itself. The program didn't blow up "because of a leak", it blew up because we exceeded some arbitrary resource threshold which may have been invisible to us. > If you do not consider leaks as part of the problem, there is a trivial way to avoid use-after-free and double-free: Simply never free any memory Indeed. And that's exactly what we see in some domains and if you've solved the other issues (e.g. bounds misses, type confusion) you've now got memory safe programs. Most general purpose software can't be written this way, but there is a whole heck of a lot of software out there which could be. > The later would fulfill your definition of "holding references to be able to free them". And that former would be characterized as "leak everything" and indeed that's entirely safe and, just as I said, to an end user this is a distinction which makes absolutely no difference.