Live data from Hacker News

Rust vs C Pitfalls

garin.io

361–370 of 379 posts

Re: Rust vs C Pitfalls

#361

Earlier quoted context omitted.

> It compiles and runs effectively instantaneously for me on Ubuntu under Windows as well, so that's very strange. Maybe file a bug? Follow-up: I tried it with -O (don't know why I didn't think of that earlier), and it runs fine. So maybe the debug version is just generating terrible code, initializing by iterating through 10 billion bounds checks or something? Anyways, more importantly, it works as I would like and…

Weird, it was fine for me with and without -O. Nothing about that code should be doing bounds checks, as it's just allocating an array.

Version: rustc 1.13.0 (2c6933acc 2016-11-07)

I remember installing it by cut and pasting one of the "curl ... | sh" commands there.

> Nothing about that code should be doing bounds checks, as it's just allocating an array.

I didn't dive into the macro definition for vec!, but I assume there is a loop in there to Copy the initialization element 10 billion times. I think you guys do bounds checking on the lower level reference to a slice that Vec uses. But I really don't know. If it's not that, then it was hanging or spinning doing something else. (Debug version of your memory allocator?)

Re: Rust vs C Pitfalls

#362

Earlier quoted context omitted.

> and so I'm stuck with C++ If you're stuck with C++, might as well do it safely: (shameless plug) https://github.com/duneroadrunner/SaferCPlusPlus

I looked briefly at your code. I don't believe it is possible to be compatible with the STL and safe in the way the Rust guys intend. I might be wrong though. What happens with your vector in this code? using namespace mse::mstd; vector data(10); double& dangling = data[0]; data.resize(100000); double crashing = dangling; You use a lot of typedefs, so I couldn't tell for sure, but I think your operator[] returns a C+…

Native C++ references are technically unsafe, so code that uses them would not qualify as "strict" SaferCPlusPlus code. In the case of your example, the "double&" is technically not kosher. The easiest way to make it safe would probably be to use a (safe) iterator instead of a native reference. So instead of

    double& dangling = data[0];
you could make it

    auto not_dangling_iter = data.begin();
    // not_dangling_iter += 0;
C++ references are the one unsafe element that does not have a "compatible" safe replacement. Unfortunately, you have to convert your references to pointers (or iterators). I don't think there is a way to create a "safe" reference with an interface compatible with native references. Apparently C++ will at some point add the ability to overload the dot operator, but I'm not sure that will be enough to be able to emulate C++ references.

And while I can overload the & (address of) operator to "prevent" you from getting a native pointer to a "safe" object, I don't know if there's a way to prevent you from getting a native reference. If you wanted to somehow enforce a prohibition on the use of unsafe C++ elements (like references), that would probably require some sort of static tool that is not yet available. But should be fairly straightforward to implement, I think.

But if you just want some confidence in the safety of the code you write, it doesn't take much effort to reliably avoid using C++'s unsafe elements.

Re: Rust vs C Pitfalls

#363

Earlier quoted context omitted.

> and so I'm stuck with C++ If you're stuck with C++, might as well do it safely: (shameless plug) https://github.com/duneroadrunner/SaferCPlusPlus

I looked briefly at your code. I don't believe it is possible to be compatible with the STL and safe in the way the Rust guys intend. I might be wrong though. What happens with your vector in this code? using namespace mse::mstd; vector data(10); double& dangling = data[0]; data.resize(100000); double crashing = dangling; You use a lot of typedefs, so I couldn't tell for sure, but I think your operator[] returns a C+…

> returning a proxy object from operator[] instead of a reference.

Oh yeah, maybe. But that would still require the ability to overload the dot operator, wouldn't it? And how would you know when to deallocate the proxy object? And presumably there would be some run-time overhead. Hmm, I don't know if it wouldn't be more practical to create a static tool (or "precompiler") to automatically convert references to (safe) pointers (or iterators).

Re: Rust vs C Pitfalls

#364

Earlier quoted context omitted.

I looked briefly at your code. I don't believe it is possible to be compatible with the STL and safe in the way the Rust guys intend. I might be wrong though. What happens with your vector in this code? using namespace mse::mstd; vector data(10); double& dangling = data[0]; data.resize(100000); double crashing = dangling; You use a lot of typedefs, so I couldn't tell for sure, but I think your operator[] returns a C+…

> returning a proxy object from operator[] instead of a reference. Oh yeah, maybe. But that would still require the ability to overload the dot operator, wouldn't it? And how would you know when to deallocate the proxy object? And presumably there would be some run-time overhead. Hmm, I don't know if it wouldn't be more practical to create a static tool (or "precompiler") to automatically convert references to (safe)…

Yes, the dot operator is a headache. As soon as you march down the road of a precompiler, you're off to building a new language. I think C++'s grammar is too much of a mess to just tweak the parse tree reliably. I suspect there really isn't a way to win at this - every workaround is partial and involves compromise.

Re: Rust vs C Pitfalls

#365
post #2

If you're fighting, you've lost. The way to convert everyone to Rust you need to be better the the competition. Not just better as in "look at my features that will make your code safer". People may see the value but think "I get on just fine without the borrow checker so it isn't too important". You need to be far better then the replacement by providing the following: * Great Tooling ( IDEs ) * Great Libraries ( Ev…

> If you're fighting, you've lost. I don't really get this attitude, it means that nothing new will ever overcome anything that's been established. > Anything that can be done easily in C or C++ will need to be easier in Rust for everyone to move You don't even need folks to move from C. Rust has had lots of success when it comes to folks completely new to systems programming learning it through Rust. Predominantly p…

I would love examples of writing about rust that didn't mention or assume any C/C++ knowledge before. So much of what I've run into assumes that knowledge.

I'd love to read tutorials or books that assume Rust is someone's first programming language, period. What would that look like?

Re: Rust vs C Pitfalls

#366

Earlier quoted context omitted.

> If you're fighting, you've lost. I don't really get this attitude, it means that nothing new will ever overcome anything that's been established. > Anything that can be done easily in C or C++ will need to be easier in Rust for everyone to move You don't even need folks to move from C. Rust has had lots of success when it comes to folks completely new to systems programming learning it through Rust. Predominantly p…

I would love examples of writing about rust that didn't mention or assume any C/C++ knowledge before. So much of what I've run into assumes that knowledge. I'd love to read tutorials or books that assume Rust is someone's first programming language, period. What would that look like?

The book doesn't assume any C/C++ knowledge.

There isn't any good "first programming language" material using Rust yet, IMHO.

Re: Rust vs C Pitfalls

#367

Earlier quoted context omitted.

> returning a proxy object from operator[] instead of a reference. Oh yeah, maybe. But that would still require the ability to overload the dot operator, wouldn't it? And how would you know when to deallocate the proxy object? And presumably there would be some run-time overhead. Hmm, I don't know if it wouldn't be more practical to create a static tool (or "precompiler") to automatically convert references to (safe)…

Yes, the dot operator is a headache. As soon as you march down the road of a precompiler, you're off to building a new language. I think C++'s grammar is too much of a mess to just tweak the parse tree reliably. I suspect there really isn't a way to win at this - every workaround is partial and involves compromise.

You know, while C++ references are technically unsafe, there is TRegisteredRefWrapper [1]. It's a safe version of std::reference_wrapper. Which kind of acts like a reference. So, if you don't mind me using std::strings instead of doubles, your example could be rewritten like

    mse::mstd::vector> data(10);
    data[0] = "some text";
    mse::TRegisteredRefWrapper dangling = data[0];
    data.resize(100000);
    try {
    	std::string crashing = dangling;
    }
    catch (...) {
    	// expected exception (not a segfault)
    	int q = 3;
    }
Does that work for you? I'm not an expert on std::reference_wrapper, so I'm not sure when it can and cannot substitute for a reference. (Btw, if it's a little verbose for you, there are shorter aliases available. Just search for "shorter aliases" in the header files.)

[1] https://github.com/duneroadrunner/SaferCPlusPlus#tregistered...

Re: Rust vs C Pitfalls

#368

To play the devil's advocate a bit, most of these are features you already get with C++, especially if you turn on all relevant warnings and treat them as errors. I can see the advantage of having things (sorta, given "unsafe") statically guaranteed for a shared codebase, but what are some compelling reasons to switch for personal projects?

Manishearth's response [1] plus Cargo [2] hits on a lot of great things about Rust.

[1]: https://news.ycombinator.com/item?id=13268955

[2]: http://doc.crates.io/

Re: Rust vs C Pitfalls

#369

Earlier quoted context omitted.

On my system (2015 MBP running Ubuntu 16.04) Rust's hello world compiles to a nearly 3.5 MB executable. Compiling the equivalent C program with clang results in an executable under 9 KB. Rust may not have a GC, but its executables are certainly fat. Note: Rust executables can be trimmed down by stripping them (not done by default, even for release builds) and using libc malloc instead of jemalloc. But even then, C wi…

> But even then, C wins by a lot. C links dynamically to its libraries. Rust does not (by default). This overhead is a constant overhead so it rarely matters. When it does, you can strip it down further and get it to the same level as C. This is not evidence of a fat runtime, just a different default compilation strategy that prodces larger binary executables. jemalloc is (an optional) part of the runtime, but the re…

Sure. It's not a fair comparison. But dynamically linking rust's std isn't an option. If you are optimizing for executable size, c wins because dynamically linking libc is possible. This is even true controlling for glibc, since most rust code also dynamically links glibc too (including hello world). In fact, rust's hello world has quite a few more shared dependencies than the equivalent c anyway: it uses libdl, librt, libpthread, and libgcc_s as well.

Re: Rust vs C Pitfalls

#370

Earlier quoted context omitted.

> But even then, C wins by a lot. C links dynamically to its libraries. Rust does not (by default). This overhead is a constant overhead so it rarely matters. When it does, you can strip it down further and get it to the same level as C. This is not evidence of a fat runtime, just a different default compilation strategy that prodces larger binary executables. jemalloc is (an optional) part of the runtime, but the re…

Sure. It's not a fair comparison. But dynamically linking rust's std isn't an option. If you are optimizing for executable size, c wins because dynamically linking libc is possible. This is even true controlling for glibc, since most rust code also dynamically links glibc too (including hello world). In fact, rust's hello world has quite a few more shared dependencies than the equivalent c anyway: it uses libdl, libr…

Dynamically linking to rust std (with a specially compiled libstd dylib) is an option iirc, just that nobody does it. Lack of stable ABI makes it less useful, but if you really need to do it there's nothing stopping you.

I suspect rust hello world using those libraries is due to a lack of LTO? Hello world doesn't need any of those.

Post reply on HN