5 ms·
Herb Sutter's comment on why it's ok is confusing to me: > Regarding the use of UB internally: It's okay and if anyone is worried about it the use of UB is ben
by digitalPhonix 2mo ago
Herb Sutter's comment on why it's ok is confusing to me:
> Regarding the use of UB internally: It's okay and if anyone is worried about it the use of UB is benign on the platforms we target (e.g., they don't involve hitting any hardware trap representations for these types)
Isn't the outcome of the UB (ie. whether it will "rm -rf /" or something else) dependent on both the target and the compiler? And the compiler (or future compiler) could plausibly make the assumption that the narrowing to an unrepresentable value will never occur and change behaviour because of it?
- pjmlp 2mo agoNo, UB is allowed special powers for compiler and standard library implementors, which is what Herb Sutter means with internal behaviour. Meaning MSVC is aware of these cases, so the compiler has special cases for it.
- wavemode 2mo agoGSL is not the standard library nor an internal runtime library. Its GitHub page claims that it supports a variety of compilers: > The GSL officially supports recent major versions of Visual Studio with both MSVC and LLVM, GCC, Clang, and XCode with Apple-Clang
- pjmlp 2mo agoIt was originally created by Microsoft and as Herb mentions "all our target platforms", so most likely it gets special treatment.
- Maxatar 2mo agoThere is absolutely no special treatment afforded to the GSL by any of the target platforms. While we can't inspect MSVC's source code, both clang and GCC do not have any support or affordance for the GSL whatsoever and it would be very unusual to expect MSVC's source code to have some kind of affordance for this library.
- achierius 2mo agoThe 'special treatment' isn't technical, it's procedural -- insofar as if, during development for a new release, MSVC were to land some changes that broke GSL, Microsoft's testing would catch that and ensure that the changes were reverted or fixed to support the latter, prior to shipping. Since they're built as part of the same operating system, they can make sure not to step on one another's toes -- which is not a guarantee that they can make to third-party applications.
- Maxatar 2mo agoI have no idea where you possibly got this idea from since the Github Issues tracker for GSL has numerous instances of new releases of MSVC breaking GSL compilation.
- ranger_danger 2mo agoI think they're saying that since they denote specific compiler versions as "officially supported", they can get away with saying the "UB" is not an issue in those versions only because they've already tested its behavior there, and anything else you compile with is untested and unsupported 'here be dragons' land. You may wish they target every possible compiler brand and version, but they are free to disagree with you and only "support" specific ones. Unfortunately this also has the same effect as the Linux kernel now in that it is no longer technically compliant with any C++ (or C) standard.
- Maxatar 2mo agoHow does a library writer testing that their library works with a specific version of a compiler that was already released have anything to do with a compiler implementation providing special treatment for that library? Your interpretation contradicts the statement that "during development for a new release, MSVC were to land some changes that broke GSL, Microsoft's testing would catch that and ensure that the changes were reverted or fixed to support the latter, prior to shipping."
- digitalPhonix 2mo agoThat's my point - GSL is NOT MSVC only, it's a general purpose library and NOT a standard library implementation of a toolchain so any compiler is expected to be able to compile it (it also explicitly targets clang & gcc).
- pjmlp 2mo agoIt was originally created by Microsoft and as Herb mentions "all our target platforms", so most likely it gets special treatment.
- aw1621107 2mo agoAt the time Herb made that comment GSL was documented as supporting XCode 12.5.1/13.2.1, GCC 10/11, Clang 11/12, and Visual Studio 2019/2022 using both MSVC/LLVM [0]. Even if MSVC had special support for GSL I'm a bit more skeptical that such support would extend to XCode, GCC, and Clang. [0]: https://github.com/microsoft/GSL/tree/99a29ce797c8337b8923f2688ba1489be6f65bc4 https://github.com/microsoft/GSL/tree/99a29ce797c8337b8923f2...
- 20k 2mo agoClang is a target for the GSL though. How can MSVC's special powers prevent this from being exploitable UB in Clang/LLVM? This code boils down to static_cast<int>(some_double); so nothing fancy is going on here
- Maxatar 2mo agoYes, this is all true but Sutter's comment is that the specific platforms that this specific implementation of the GSL targets results in the correct output. The platforms officially supported are: GCC 12, 13, 14 XCode 14.3.1, 15.4 Clang 16, 17, 18 Visual Studio with MSVC VS2019, VS2022 Visual Studio with LLVM VS2019, VS2022
- afdbcreid 2mo agoThen this is, unfortunately, entirely wrong. Here's an example causing a segfault when there is a bound checks that the compiler omits: https://godbolt.org/z/8f6rv4dja https://godbolt.org/z/8f6rv4dja The example is adapted from a Rust example shown by @RalfJung in https://lobste.rs/s/ba2yfy/c_float_int_conversion_can_be_undefined https://lobste.rs/s/ba2yfy/c_float_int_conversion_can_be_und....
- wavemode 2mo agoFor what it's worth, a GSL developer later reopened that GitHub issue and stated that they're going to look into fixing the UB. Sutter may have just been stating an assumption. https://github.com/microsoft/GSL/issues/786#issuecomment-5133269178 https://github.com/microsoft/GSL/issues/786#issuecomment-513... > I'll raise this issue in the next internal GSL sync. I'd agree with y'all that this behavior: https://godbolt.org/z/4Tr1fe9xG https://godbolt.org/z/4Tr1fe9xG is undesirable
- mort96 2mo agoBut ... surely Sutter ought to know better than to say "because the hardware handles this conversion reasonably, it's a benign case of UB"? Surely he knows that compilers can and will optimize based on the assumption that UB never happens? The problem isn't, "oh no what if my CPU's float->int conversion instruction traps", that's an extremely naive way to think about UB. Everyone who has thought seriously about UB in C++ for any length of time knows this. It's worrying that this was Sutter's response.
- tialaramex 2mo agoI think this actually demonstrates why Rust's safety culture is what's crucial, not the safety technology they have built to enable that culture and which is relatively easier to duplicate. The natural instinct of humans is to deny problems. Their safety culture very strongly encourages Rustaceans encountering the equivalent issue [this really happened, you could write this nasty conversion bug in Rust 1.0 no problem but for years now Rust panics] to accept that there is a safety problem - and from there they can begin actually addressing the problem rather than pretending it doesn't exist. It's not perfect, but the alternatives are definitely worse. The technology doesn't do this. The Rust compiler would be entirely OK with Rust shipping a standard library where safe APIs like Vec::pop can induce Undefined Behaviour. That's not allowed culturally, but technically Vec::pop already has an unsafe block, it could cause UB if it wanted to.
- ameliaquining 2mo agoNitpick: Rust doesn't panic in this situation, it saturates (i.e., returns the largest possible value for the given integer type). Among other reasons, because a lot of existing programs that triggered this UB happened to work in practice, and would have experienced the panicking behavior as a severe regression. This case also shows the limits of Rust's safety culture; they knew about the problem for a long time, and could have fixed it right away if they'd been willing to make programs that do a lot of float-to-int casts eat a performance regression, but a number of users objected strongly to this. So it remained unfixed until they figured out a way to make it fast enough that no one would really notice.
- LoganDark 2mo agoUB is bad not because it actually leads to any particular result on any particular platform or compiler, but because semantically it invalidates assumptions about a program. Rust is explicit on this, but it absolutely still applies to C/C++.
- em3rgent0rdr 2mo agoWell because it could lead to any result on some platform or compiler, it invalidates assumptions about the program.
- LoganDark 2mo agoUB invalidates assumptions about the program not necessarily because it leads to arbitrary behavior in practice, but because it leads to arbitrary behavior in spirit. Even if there is no compiler in existence where the UB causes a problem, that does not make the program correct. UB is about whether the program is correctly defined, not about whether it works or not.
- jcranmer 2mo agoIn LLVM, the result of floating-to-int conversion that is out of range of the int is a poison value, which means you get essentially the full unpredictability of UB. That said, I'm a little hard-pressed to think of optimizations that would actually take advantage of poison, because floating-point range isn't really computed in the optimizer.
- mort96 2mo agoHere's (my modified version of) an example someone came up with on lobste.rs: https://godbolt.org/z/e69b4Tqbs https://godbolt.org/z/e69b4Tqbs I don't know exactly which optimization passes do what, but a few observations: * The 'foo(unsigned int n)' function should never return a value that's greater than 'n', since it returns 'i < n ? i : n'. * The value printed by the 'foo' function should always be the same as the value that's returned. Yet the value it prints is 2700624104 (which is greater than 'n', which is 10 in this case), and the returned value is 2700623376, which is different. (The exact numbers vary run to run) If the conversion "just" resulted in a bogus value, we would have expected some number <=10 to be printed two times.
- 20k 2mo agoYeah Herb's 100% wrong here. Its common when people are downplaying the memory safety issues with C++ that they say things like this, but its completely incorrect. All invoked UB is potentially equally serious, and this is exploitable memory unsafety. Compilers can and do optimise away this kind of stuff (as other people have explained here) There's also important context in that Herb is currently one of the people leading the current memory safety approach for C++
- throwawayffffas 2mo agoAt this point of time Herb Sutter was working for Microsoft. When he says "we" the compiler team is included. What he means is that, it works for Microsoft as it is and zero fucks are given for other compilers and platforms.