On Sat, Apr 17, 2021 at 4:21 PM Willy Tarreau <w@xxxxxx> wrote: > > Well, I can't express how much I hate abstractions because I constantly > need to know what it's doing under the hood, and I spend my time reading > the output asm code because I always want to confirm my assumptions about > the compiler not cheating on me (and not hitting one of its bugs), > especially after C compilers have become so smart that they completely > replace your code with what they think is better for you, (including > nothing), so I guess all of this is really not for someone like me. Concerning compiler bugs etc.: as you mention, nowadays that applies to both C and Rust. Manually inspecting the output asm does not really scale anymore because we need to worry about all compiler versions out there, including future ones, for both GCC and Clang. So we would need to disable optimizations, or reduce the set of supported compiler versions, or automatically check the generated asm (like in the compiler's own test suites), or keep binary blobs after checking (like in some safety-critical domains), etc. Since none of those are really doable for us (except perhaps for small subsets of code or unit tests), we need other ways to help with this. Rust provides several here. For instance, the UB-less subset means less surprises and less double-checking if some particular construct is UB and may give problems later on. Similarly, Rust is actually more explicit in many cases than C, to reduce surprises further. For instance, regarding implicit type conversions, none of these compile: fn f1(n: i32) -> i64 { n } fn f2(n: i32, m: i64) { n + m; } fn f3(b: bool) -> i32 { b } fn f4(n: i32) -> bool { n } fn f5(n: i32) -> i32 { if n { 42 } else { 53 } } Building abstractions also helps to ensure you get the semantics you want in the face of smart optimizers -- rather than the opposite. For instance, continuing with the integer examples, you may use a `NonZeroU32`. Or a `Wrapping<u32>` for intentional wrapping integer arithmetic, etc. Cheers, Miguel