Can we throw Python in too? Python has more safety than any of these languages, yet it's always left out of these discussions.
Safety: A comparaison between Rust, C++ and Go
101–110 of 188 posts
Re: Safety: A comparaison between Rust, C++ and Go
#102Earlier quoted context omitted.
Oh I completely agree that defaults matter, and I wouldn't advise anyone to go start some big C++ project unless they had a very good reason to. But Rust vs. C++ is not an apples-to-apples comparison in this regard: Rust got a clean slate and was willing to cut ties with engineer-millenia of existing high-value software to do it. In a perfect world Rust wouldn't be ambivalent at best and hostile at worst to C++ inter…
Rust isn't hostile about C++ interop, it's that between native interop (which requires dealing with templates and memory unsafety) and safety, Rust prioritized safety, while Carbon is trying the alternate approach. The behavior of C++ is simply hard to interface with while providing the assurances Rust gives you. Edit: how many languages have native C++ interop that supports the whole language? Would love to hear of…
Re: Safety: A comparaison between Rust, C++ and Go
#103Earlier quoted context omitted.
I dunno man. I've done C, C++, JavaScript and TypeScript professionally for significant chunks of my career, and the trend that I've observed has overwhelmingly been towards stricter compilers. For example in the front-end world, TypeScript has absolutely exploded in adoption. Everyone could be still using JavaScript, but companies from startups to huge corporates have explicitly decided they want compile type safety…
Oh I think we probably see largely eye-to-eye. My weapon of choice when there are no other constraints is Haskell, and one reason I really like Rust is that I can get a lot of the Haskell features I like in a highly-performant setting. Most of the C++ I maintain these days is in whole or in part generated by Haskell. And if I have to write something fast by hand and it doesn't need to link to stuff I need, I reach fo…
Can you expand on that? I'm currently researching something similar but lower level & lisp instead of Haskell. It would help to see some existing examples to figure out if it's worth it or not.
Re: Safety: A comparaison between Rust, C++ and Go
#104Earlier quoted context omitted.
I find it so weird that the Rust community is borderline evangelical about memory safety when a) it's not actually memory safe once you start doing heavy shit b) modern C++ is quite memory safe and c) there are so many other great reasons to like Rust. Memory safety in serious systems software is something that you approach asymptotically and/or probabilistically. Rust makes it easier to be memory safe in a lot of sc…
> a crashed program is a crashed program whether I dereferenced a null pointer or was poking around in a slice with multi-byte Unicode characters in it They aren't the same thing though, that's the point. Dereferencing a NULL pointer isn't guaranteed to crash. In fact if you are writing through the pointer, you may even have a security issue on your hands (rce, etc). Safe Rust may have runtime errors that "crash" the…
I've spend weeks chasing down single instances of this on multiple projects. The nasty part is you have no predictability in if it's going to be one that crashes immediately, silently writes garbage(hopefully not to disk!), is a latent lurking crash or security vuln.
If you trash the stack then there's a good chance you lose the backtrace as well which can make a hard to debug issue become "find the needle in the haystack". I hope it's something that reproduces quickly and consistently because otherwise you're in for a ride.
Re: Safety: A comparaison between Rust, C++ and Go
#105This would be a better article if the UB in the C++ example wasn't blindingly obvious-- no C++ programmer worth a damn would ever write this.
Why is this such a common defense for the peculiarities of C++? I see it pop up at least a couple of times, anytime C++ is criticized. I don't have anything against taking pride in one's skill and craftsmanship, but excusing a tool's failings purely on the basis that one needs more skill to wield it and avoid those failings? I want to have that same level of skill and have my tool multiply my skill's output to the ma…
It would be one thing if this required skill, but this example is downright silly. Some other people here have posted more reasonable version, that might actually occur in the real world(like the example with std::span)
Re: Safety: A comparaison between Rust, C++ and Go
#106Earlier quoted context omitted.
Rust's thread safety only applies to the special case of those threads accessing in process data segments. Rust's type system can do very little to help when those threads are accessing the same record on a database without transactions, OS IPC on shared memory, manipulating files without locks, handling hardware signals, handling duplicate RPC calls,... Yeah but that ultimately requires an unsafe block, kind of true…
This has been a recurring theme from you, but in the cases you're describing the risk is only a race condition (no general solution is possible) and not a data race (which safe Rust is able to deny by design). These are categorically different problems.
Re: Safety: A comparaison between Rust, C++ and Go
#107Earlier quoted context omitted.
Rust's thread safety only applies to the special case of those threads accessing in process data segments. Rust's type system can do very little to help when those threads are accessing the same record on a database without transactions, OS IPC on shared memory, manipulating files without locks, handling hardware signals, handling duplicate RPC calls,... Yeah but that ultimately requires an unsafe block, kind of true…
This is a point that you constantly bring up in these threads, do you think most developers believe that data race safety should extend beyond the bounds of the process? One thing that Rust’s type system does allow you to do is define a consistent manner in which to access external systems, even add types that will mimic the same safety. Is it perfect? Will it protect you from a different process working against the…
Maybe many Rust devs don't care.
Re: Safety: A comparaison between Rust, C++ and Go
#108Earlier quoted context omitted.
> In C++ the community "default" is `absl::flat_hash_map`/`folly::F14`, which use SIMD to compare a whole stripe of key-prefixes simultaneously. Just to be clear, the Rust HashMap does the same thing.
TIL. Thanks for letting me know that: https://doc.rust-lang.org/src/std/collections/hash/map.rs.ht... I don't know how I missed this, is the Swiss port a fairly recent development?
The port is a little older, 2018. The idea was famously explained at CppCon 2017, I don't know whether Google had published on Swiss Tables before that year.
Re: Safety: A comparaison between Rust, C++ and Go
#109Earlier quoted context omitted.
>The bad C++ code is in the very first line of the "make_appender" definition: capturing the closure's environment by reference is nonsense: It is equivalent to returning a reference to an argument. If it is so bad, it should (in the sense of how things would be in an ideal world) not compile. >It is not, then, a closure at all. It is a closure because all variables are closed-over and there are no free variables in…
> If it is so bad, it should (in the sense of how things would be in an ideal world) not compile. Yes, C++ can be a bad solution to a lot of problems, and that's okay. Use rust if you need a machine guarantee for memory safety (or you just like the language), you can use Go if you just don't care about that at all and want the language to take care of it. But you can use C++ for non-critical software that needs to be…
Rust has the least mental overhead of any language I've ever used. The compiler literally takes all the mental overhead away.
Re: Safety: A comparaison between Rust, C++ and Go
#110Disingenuous. The bad C++ code is in the very first line of the "make_appender" definition: capturing the closure's environment by reference is nonsense: It is equivalent to returning a reference to an argument. It is not, then, a closure at all. Using a correctly-defined make_appender would not, then, produce undefined behavior when you use it, with or without "move". What the author has done here was to take a too-…
You can add [[clang::lifetimebound]] on the suffix parameter and you get :21:35: warning: temporary whose address is used as value of local variable 'append34' will be destroyed at the end of the full-expression [-Wdangling] auto append34 = make_appender({3, 4});
test.cpp:16:45: error: Using object that is a temporary. [danglingTemporaryLifetime]
assert((std::vector{1, 2, 3, 4} == append34({1, 2}))); // FAIL: UB
^
test.cpp:3:12: note: Return lambda.
return [&](std::vector&& items) {
^
test.cpp:2:50: note: Passed to reference.
auto make_appender(std::vector const& suffix) {
^
test.cpp:4:36: note: Lambda captures variable by reference here.
return append(move(items), suffix);
^
test.cpp:15:35: note: Passed to 'make_appender'.
auto append34 = make_appender({3, 4});
^
test.cpp:15:35: note: Temporary created here.
auto append34 = make_appender({3, 4});
^
test.cpp:16:45: note: Using object that is a temporary.
assert((std::vector{1, 2, 3, 4} == append34({1, 2}))); // FAIL: UB