News for hackers. Stuff that matters.
Re:Rust vs C Pitfalls by lacampbell on Tuesday December 27, 2016 @05:12PM (#13266648)
C is a very small and very portable language. Rust is not. I wondering why people bother comparing them at all.
Re:Rust vs C Pitfalls by pornel on Tuesday December 27, 2016 @07:57PM (#13267636)
Because Rust is IMHO the first viable replacement for C. Well-written C programs translate almost 1:1 to Rust.

It can do (roughly) everything C can, i.e. it's natively compiled, gives control of memory layout, and doesn't depend on a GC runtime.

Previous C killers were either dependent on a fat runtime (which isn't a big problem in general, but is a problem for some of niches dominated by C), or didn't offer meaningful improvement in safety/concurrency/expressiveness.

Re:Rust vs C Pitfalls by blub on Wednesday December 28, 2016 @06:52AM (#13269942)
Easy on the propaganda there.

* "First viable replacement for C" - C++ was invented decades before Rust.

* "Well-written C programs translate almost 1:1 to Rust" - C programs can be compiled with minimal changes as C++.

* "or didn't offer meaningful improvement in safety/concurrency/expressiveness." - C++ offers major improvements in all of those areas.

A lot of C programmers don't want to switch to C++ and they won't want to switch to Rust either, because they favor simplicity and neither Rust nor C++ are simple. They'll probably switch to golang for some stuff if anything and just stick to C for the rest.

Re:Rust vs C Pitfalls by pornel on Thursday December 29, 2016 @06:39AM (#13276802)
I'm a C programmer who switched to Rust.

Rust is complex because it's powerful.

C++ is complex because it's a mashup of overlapping features from different eras.

I don't write C++, because whatever I write will crash for subtle reasons and I'll be told it's my fault, because of course you don't do this when you use that feature.

I can write Rust with all its complexity, and as long as I get it to compile, I'm confident it works more reliably than any C++ that I could have written.

Re:Rust vs C Pitfalls by cderwin on Wednesday December 28, 2016 @12:42AM (#13268688)
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 wins by a lot.

Relevant blog post: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executab...

Re:Rust vs C Pitfalls by Manishearth on Wednesday December 28, 2016 @01:38AM (#13268869)
> 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 rest isn't.

Re:Rust vs C Pitfalls by cderwin on Thursday December 29, 2016 @12:52AM (#13275867)
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 by Manishearth on Thursday December 29, 2016 @01:32AM (#13275999)
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.

Re:Rust vs C Pitfalls by mmstick on Wednesday December 28, 2016 @01:39AM (#13268871)
Not a particularly fair comparison though, as that C binary is loading dynamic libraries that are already in memory. Case in point: that C program needs the C standard library, but by default that library (glibc) is dynamically loaded. Rust is not offering the Rust standard library as a dynamic library, hence the larger size. Not to mention, interfacing with C functions in the kernel.

You'll get different results if you compile them with musl for truly static and fair binary size comparisons.

Re:Rust vs C Pitfalls by 0xFFC on Wednesday December 28, 2016 @03:13AM (#13269182)
I am no expert, but you should compile barebone executable for comparing executable size! not "hello world", because hello world does use shitload of library (for printing and loading and stuff), and those ones in C is compiled in dynamic, but in rust those compiled inot executable itself.

if I remember correctly you should compile with --nostd flag and provide _start function for loader to load your executable!

you can do same with rust too (But I think you should provide a special flag for compiler). You can find all of it on documentation.

Re:Rust vs C Pitfalls by gpderetta on Tuesday December 27, 2016 @05:13PM (#13266665)
I doubt that a significant amount of C programmers will switch to Rust. On the other hand, rust is very attractive for us C++ programmers.
Re:Rust vs C Pitfalls by zerofan on Tuesday December 27, 2016 @05:49PM (#13266924)
To me it's almost the opposite. I like C a lot, but I ended up compromising on C++11 because in some programs I need more features to keep the implementation clean. I pay the cost of a messy language (C++) when implementing my libraries in order to have simpler applications that use those libraries.

I've written C-like programs in Rust, and that goes very well. But I really like function overloading, generic operators that I can overload from the left and the right, integer parameters for my templates/generics, copy semantics as the default (opt-in for moves), placement new, explicit destructors, and maybe a few other niceties. Rust does none of these things the way I want, and so I'm stuck with C++.

There are a few other things where I think Rust just made the wrong choices and didn't improve over C++. I've always hated the dichotomy in C++ strings between const char* pointers and an actual string class. Rust had the chance to make strings feel as comfortable as integers, but instead they introduced their own dichotomy with String and &str.

Speaking of integers, Rust's choice of 32 bit integers as the default for literals is painful given that every machine most of us will ever care about is now 64 bit. I routinely deal with arrays and files that are too large for a 32 bit integer. This means I have to remember to suffix all of my integers in for loops etc... C++ has this wrong too (backwards compatibility), but Rust had a chance to make a clean start and did not.

Re:Rust vs C Pitfalls by mmstick on Wednesday December 28, 2016 @02:15AM (#13268979)
> Rust had the chance to make strings feel as comfortable as integers, but instead they introduced their own dichotomy with String and &str.

It makes perfect sense when you understand the differences and reasoning behind it. A `String` is a heap-allocated string that can grow in size. On the other hand, a `str` is basically a fixed-size string array, but you'll never interact directly with this type because there's no point in it. It's tucked away inside the `String` that created it.

Meanwhile, an `&str` is a slice of that fixed-size `str` array that's hidden within the `String`. You can think of a `str` as an `[char]` with it's own special `str` methods, and an `&str` as an `&[char]` which has access to all of the `str` methods as well.

> Speaking of integers, Rust's choice of 32 bit integers as the default for literals is painful given that every machine most of us will ever care about is now 64 bit. I routinely deal with arrays and files that are too large for a 32 bit integer.

I'm pretty sure the default integer is a `usize`, which is 32-bit on 32-bit systems and 64-bit on 64-bit systems.

Re:Rust vs C Pitfalls by Manishearth on Wednesday December 28, 2016 @12:50PM (#13272181)
No, the default integer is u32. If type inference can't provide a better type, Rust will pick u32. If type inference can pick a better type it will use it. So if you create an unsuffixed int literal and use it for indexing, that literal will be a usize.

Rust will type error if you try to use u32s with an array so it's all good though. Just means that you need to specifically `: usize` things.

If you need an integer type for counting stuff, u32 is fine. If you actually need to talk about memory, use usize. The compiler will force you to do it.

Re:Rust vs C Pitfalls by ayosec on Wednesday December 28, 2016 @02:37PM (#13273026)
> No, the default integer is u32

Maybe I'm missing something, but it seems to be i32: https://play.rust-lang.org/?gist=c79d4afef7fa20c81ba14de61f5...

Re:Rust vs C Pitfalls by mmstick on Wednesday December 28, 2016 @01:56PM (#13272682)
That makes sense. I've never noticed what the default size was, but because it always worked with indexing, I assumed that it was always usize.
Re:Rust vs C Pitfalls by Manishearth on Wednesday December 28, 2016 @02:22PM (#13272887)
I believe it used to be uint (usize) back in pre-1.0, and IIRC inference didn't work well or wasn't supposed to work at all. I recall needing explicit prefixes on my int literals back then. No longer the case.
Re:Rust vs C Pitfalls by steveklabnik on Tuesday December 27, 2016 @06:10PM (#13267081)
How would you have gone about making Strings be "as comfortable as integers"?

Arrays are indexed by usize, so if you're on a 64-bit machine, then you shouldn't need a cast. It's _unconstrained_ numbers that default to i32, not anything without a suffix.

Re:Rust vs C Pitfalls by zerofan on Tuesday December 27, 2016 @07:47PM (#13267587)
> How would you have gone about making Strings be "as comfortable as integers"?

I would prefer a str be a str be a str, regardless of how you got it. Lowercase type-name and fundamental like an integer.

I'm fairly certain I understand why Rust made the choice they did. I've read the forum threads at HN, Reddit, and users.rust-lang, and I've seen previous replies by you and other Rusties, so I hope you won't try to educate me about the performance advantages of having slices as references and another string type as an ownership class or why we need OsStr and friends.

If strings are the fundamental processing concern in your application, then I think you should be able to opt-in to that kind of micro-optimization and complexity, but it would've been better to spare the rest of us who have different concerns. I don't want to become a string expert to build a filename, and the default implementation could (at least conceptually) be always on the heap for all I care. Go one step further and implement the "small string optimization" (Alexandrescu's fbstring), and you'd probably get back most of the performance without nearly the complexity.

> Arrays are indexed by usize

I've spent the last half hour trying to troubleshoot why this line hangs:

    let aa = vec![1u8; 10e9 as usize];
However, I'm at home using the Ubuntu under Windows thing, so maybe there's some bad mojo between Rust and my less than usual setup. (If you're interested, I have 32 Gigs of memory, and the equivalent C malloc and memset code runs just fine, so I don't think Rust is doing the right thing here...).

Anyways, I wanted to test the commented out line, but I'm stuck for now. If that line would work, I'll admit I was wrong, but I think the uncommented line shows a similar complaint.

    for ss in 0..63 {
        //print!("{}\n", aa[1<<ss]);
        print!("{}\n", 1<<ss);
    }
> It's _unconstrained_ numbers that default to i32, not anything without a suffix.

Looking at the present and the future, why is that a sensible default? Both x64 and ARM are going to use a 64 bit integer register for the operations, and many of those operations are going to be 1-clock throughput. You can probably find a counter example, but 32 bit integers aren't generally faster than 64 bit ones.

Re:Rust vs C Pitfalls by mmstick on Wednesday December 28, 2016 @02:28AM (#13269020)
> I would prefer a str be a str be a str, regardless of how you got it. Lowercase type-name and fundamental like an integer.

The lowercase type names are reserved to primitives. The String type is not a primitive but a comprehensive data structure, hence the capital S. The String type contains an `str` primitive though, along with size information.

> I don't want to become a string expert to build a filename, and the default implementation could (at least conceptually) be always on the heap for all I care.

Is it that hard to understand that when you create a string, you will create it as either a `String` or `PathBuf`? File methods are designed to automatically convert input parameters into a `&Path` so it doesn't matter what string structure you provide.

There is also no way (currently) to create a stack-allocated string with the standard library out of the box. You can do this with crates like `arrayvec` though. It's very much opt-in for that performance.

let path = String::from("/tmp/file");

let mut file = File::open(&path).unwrap();

> Looking at the present and the future, why is that a sensible default? Both x64 and ARM are going to use a 64 bit integer register for the operations, and many of those operations are going to be 1-clock throughput. You can probably find a counter example, but 32 bit integers aren't generally faster than 64 bit ones.

No need to use a 64-bit integer when you only need a 32-bit integer. You can fit two 32-bit integers into a single 64-bit integer and perform a calculation on both simultaneously with a single cycle, versus spending two cycles to calculate two 64-bit integers. There's also no need to pay that memory cost either.

Re:Rust vs C Pitfalls by steveklabnik on Tuesday December 27, 2016 @07:56PM (#13267633)
> so I hope you won't try to educate me

No, I'm interested in what tradeoffs you would have made differently. I now understand. Thanks! (I disagree, but at least I understand.)

> why this line hangs:

It compiles and runs effectively instantaneously for me on Ubuntu under Windows as well, so that's very strange. Maybe file a bug?

> I think the uncommented line shows a similar complaint.

Yes, there's no constraint on that literal, so it's going to be an i32. When we made this decision, we did some analysis, basically no numbers in real world programs weren't constrained, it was often tests, toy programs, and documentation. It should be a rare thing. YMMV.

> why is that a sensible default?

Your assertion about the speed was the opposite of what was asserted while we had the discussion, basically. And not everybody is running on 64-bit hardware, so it's a broader default.

Re:Rust vs C Pitfalls by zerofan on Tuesday December 27, 2016 @10:10PM (#13268158)
> 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 does not behave as a 32 bit integer. I think I understand what you mean by "constrained" now. And clearly, I was wrong.

However, if most un-suffixed integers in real-world programs will become constrained (as you claimed), this further confuses me why i32 is the unconstrained choice. It doesn't seem like something so rare could be enough of a performance problem to justify being anything but the largest supported size.

Re:Rust vs C Pitfalls by steveklabnik on Wednesday December 28, 2016 @12:14PM (#13271905)
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.
Re:Rust vs C Pitfalls by zerofan on Wednesday December 28, 2016 @07:51PM (#13274947)
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 by zerofan on Tuesday December 27, 2016 @08:18PM (#13267731)
> basically no numbers in real world programs weren't constrained, it was often tests, toy programs

The fact that C and C++ compilers generally chose to leave int at 32 bit on 64 bit platforms, combined with the standards requiring "usual promotions" for smaller types to go to int bites me all the time. I'm very happy that Rust dodges the promotions problem altogether, and I'm sorry if I'm wrong about the array subscripting thing (does the snippet I provided panic at 1<<32 or 1<<34?).

> And not everybody is running on 64-bit hardware, so it's a broader default.

That argument could be used to justify 8 or 16 bit integers... :-)

Re:Rust vs C Pitfalls by steveklabnik on Tuesday December 27, 2016 @08:23PM (#13267750)
> (does the snippet I provided panic at 1<<32 or 1<<34?).

Overflow is a "program error", and in debug builds, is required to panic. In other builds, if it does not panic, it's required to two's compliment overflow. Rustc currently just overflows, but in the future, we'll see.

That's true except our 16 bit support is nonexistant at the moment :)

Re:Rust vs C Pitfalls by zerofan on Tuesday December 27, 2016 @08:33PM (#13267785)
> That's true except our 16 bit support is nonexistant at the moment :)

If you pay attention to your usage statistics, I'll bet you drop 32 bit support before the May 2025 deadline we were discussing in the other thread.

Re:Rust vs C Pitfalls by steveklabnik on Tuesday December 27, 2016 @09:00PM (#13267885)
We'll see!
Re:Rust vs C Pitfalls by gpderetta on Tuesday December 27, 2016 @06:04PM (#13267029)
> But I really like function overloading, generic operators that I can overload from the left and the right, integer parameters for my templates/generics, copy semantics as the default [etc.]

I do too, and I'd like to think that rust needs all those things to be a replacement, but realistically I think that the only killer feature that rust is still missing is reasonable interoperability with C++ (which admittedly might require implementing a few of those features).

Disclaimer: I have been following rust since Graydon initial announcement, but I have yet to write a single line of code in it.

Re:Rust vs C Pitfalls by akiselev on Wednesday December 28, 2016 @02:29AM (#13269021)
What do you mean by "reasonable?" There are several crates that provide inline C++ macros on both nightly (rustcxx) and stable (rust-cpp). I haven't used the latter but the former works really well (albeit using a gcc specific feature). I usually break out the C++ code into a wrapper (unless its a few lines) to make it more idiomatic Rust but at the end of the day, there aren't that many hoops to jump through.
Re:Rust vs C Pitfalls by duneroadrunner on Wednesday December 28, 2016 @06:32AM (#13269882)
> 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

Re:Rust vs C Pitfalls by zerofan on Wednesday December 28, 2016 @07:37PM (#13274894)
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<double> 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++ reference right?

The problem here is there is only one operator[] for both reading and writing. This is a simple contrived example, and taking a reference like that looks artificial, but there are a lot of other ways in real programs to stumble on to this. (I don't think it's as bad as the Rusties do, but I stumble into this bug once or twice a year...)

The Rust folks seem to believe you need a borrow checker to solve this problem, but I think that a different container library in C++ could do the trick. For instance, favoring value copies instead of references, and returning a proxy object from operator[] instead of a reference.

Re:Rust vs C Pitfalls by duneroadrunner on Wednesday December 28, 2016 @09:20PM (#13275274)
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 by duneroadrunner on Wednesday December 28, 2016 @09:34PM (#13275323)
> 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 by zerofan on Wednesday December 28, 2016 @10:19PM (#13275435)
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 by duneroadrunner on Wednesday December 28, 2016 @11:40PM (#13275658)
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<mse::TRegisteredObj<std::string>> data(10);
    data[0] = "some text";
    mse::TRegisteredRefWrapper<std::string> 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 by Scuds on Tuesday December 27, 2016 @05:30PM (#13266781)
Do you think we'll see major games having significant engine components being written in Rust?
Re:Rust vs C Pitfalls by mmstick on Wednesday December 28, 2016 @02:31AM (#13269026)
DICE and others have been investigating and using it to create tools for developing games. There is interest in using it within game engines, but there's just the issue of Rust support for major consoles. There is great interest in the PC gaming world though that's not constrained by console support.
Re:Rust vs C Pitfalls by gpderetta on Tuesday December 27, 2016 @06:01PM (#13267008)
I don't work in that field, but I doubt game programmers will be early adopters of rust, as I think they mostly don't care about memory safety.
Re:Rust vs C Pitfalls by Crespyl on Wednesday December 28, 2016 @12:58PM (#13272234)
There's been some interest, but I think the likes of jblows Jai language that emphasize rapid development and programmer convenience over correctness will likely catch on faster.
Re:Rust vs C Pitfalls by lacampbell on Tuesday December 27, 2016 @05:31PM (#13266786)
I appreciate rust making a break from C++ and cleaning up some of the warts, immutability by default, having real modules etc. But I am not really impressed with its memory management thing. It's a bit tiresome to check stuff with valgrind, sure, but I don't have to worry about making cyclic data structures satisfy the borrow checker. I don't see the trade off as worth it.
Re:Rust vs C Pitfalls by groovy2shoes on Tuesday December 27, 2016 @07:56PM (#13267632)
C has also been relatively stable for the last 25 years or so. Rust changes every 6 weeks.

Yes, the language is supposedly not undergoing breaking changes without strict deprecation and feature-gating. However, as new features are added to the language, libraries are usually updated to leverage them, and suddenly you are also forced to keep up with that rapid release cadence to ensure your project still builds.

Meanwhile, C code from the mid-80s still compiles with modern compilers, often without any changes whatsoever, and without any feature gates.

Don't get me wrong. I like Rust and what the project is trying to do. But I see two major problems that are preventing me from using it for anything major at the moment: 1) the extremely rapid rate of change, and 2) difficulty of implementation (both of which, taken together, lead me to expect no serious alternative implementations any time soon).

Before I will be willing to adopt Rust as a C replacement in full, there needs to be a solid, stable language definition that compiler writers can target and programmers can rely on for a good chunk of time. I have a feeling we'll get there eventually once the number of new, useful features that are missing from the language starts to dwindle and it begins to stabilize naturally.

In the meantime, I'd settle for an "LTS" release or something. That could work.

Re:Rust vs C Pitfalls by tatterdemalion on Tuesday December 27, 2016 @10:47PM (#13268292)
I don't understand. Rust 1.0 code will compile on Rust 1.14, in the same way that C code from the 80s will compile on modern C compilers. That's what "backwards compatible" means!

Your dependencies don't upgrade themselves. Its true that if you upgrade your dependencies, they may depend on a more recent verison of rustc, in which case you need to upgrade rustc as a part of upgrading that dependency. But if you are using rustup this is not harder than upgrading those dependencies - probably easier in fact.

In exchange for downloading a tarball at most every six weeks, you get a language that is developing new features.

Re:Rust vs C Pitfalls by mmstick on Wednesday December 28, 2016 @01:46AM (#13268890)
The problem with your concept is that C does not offer an official standard library and compiler suite, so you're trying to compare the C spec to the Rust standard library + compiler.

The actual Rust API has changed very little since the 1.0 release. All the changes that have occurred have been mere additions to the language -- nothing breaking. Hence why the 1.0 release was termed as a 1.0 release. There won't be anything happening that causes breakage until a 2.0 release.

You'll find that C compiler and library development is also rapid like Rust. There's new versions of LLVM/Clang and GCC being released on a regular basis. There are constant updates to musl and glibc. These changes tend to break far more often than Rust, which is developed in Rust and can be guaranteed to be much safer.

That Rust is being openly developed on GitHub with a significant number of developers, with an official compiler + library + doc + comprehensive suite of resources collectively being maintained, that's a significant incentive to work with Rust. There's a solid RFC process to prevent anything silly from entering the language. No random decisions by random people -- it takes a lot of convincing to add a new feature to Rust.

Re:Rust vs C Pitfalls by groovy2shoes on Wednesday December 28, 2016 @06:10AM (#13269807)
C does have a standard library. It's described in full in the ANSI/ISO/IEC standard for the C programming language, and it's on your system, likely called libc or something along those lines.

Anyway, I don't think that's a problem with my concept at all. What I want for Rust, and what I think will eventually be feasible for Rust as the language matures, is a standard that can be shared by compiler writers and Rust programmers. A standard is worthless if it's inadequate (see ISO Pascal or ISO Basic, for example), so it's a good thing that right now Rust is iterating quickly and improving rapidly. But eventually, there's going to need to be a stationary target for compiler writers to aim for, and for Rust programmers to be confident that the code they write today won't be littered with deprecated features, anti-patterns, and worst practices tomorrow.

Frankly, I don't see wide adoption happening in the corporate world until there's an LTS compiler at the very least.

Re:Rust vs C Pitfalls by mmstick on Wednesday December 28, 2016 @02:13PM (#13272811)
> C does have a standard library. It's described in full in the ANSI/ISO/IEC standard for the C programming language, and it's on your system, likely called libc or something along those lines.

What you're describing is the spec and not the implementation. An implementation would be glibc (GNU Libc with open source proprietary extensions) and musl (MIT implementation that strictly adheres to spec). These libraries are updated often.

Meanwhile, Rust offers more than just a specification. It offers an implementation. This is libcore-rust + libstd-rust. This is what receives updates each 6 weeks. It also offers a compiler that comes with it, rustc, which is also what receives updates each 6 weeks.

Rust strictly adheres to semantic versioning, so changes to the API are not allowed without a major version bump. Code that was written for Rust 1.0 will still compile on Rust 1.15. Code written for Rust 1.15 may not compile for a Rust 1.0 compiler though because bumping the second version implies adding new features. Rust doesn't yet utilize a patch version though. There's never been any critical issues discovered in each stable release.

> Frankly, I don't see wide adoption happening in the corporate world until there's an LTS compiler at the very least.

Can't say that I understand why a LTS compiler would be required for adoption. Many in the corporate world are already using Rust, either publicly as an official friend of Rust or privately in smaller projects. There's nothing a LTS compiler would provide that would be beneficial to the corporate world. Semantic versioning and the ease of managing Rust toolchains with rustup has everything pretty well covered.

Re:Rust vs C Pitfalls by groovy2shoes on Sunday January 01, 2017 @01:31AM (#13294905)
I can only attest to my own experiences at various corporations, and those corporations want to thoroughly vet any software platform before targeting it and supporting it for customers.

As to my own concerns (rather than corporate concerns), here's where I'm coming from:

When I wind up choosing C for a particular project, I don't use it because I like it (I don't particularly like C). Typically, I use it because there are three factors I've considered: 1) This particular project needs the low-level access or performance characteristics provided by a systems language, and 2) C is such a language, 3) C is ubiquitous.[1]

The thing is, every platform for the last 25 years or so has had a reliable ANSI C compiler. If the goal of my project is to be cross-platform, then a carefully-written application in standard C is guaranteed to be able to reach the widest number of users, many of whom won't have to do or install anything to build my application, since many environments already include a C compiler without any additional installation necessary (think Unix, BSD, a shrinking number of Linux distros, ...). Using C puts my application on the path of least resistance for potential users.

Similarly, if I'm writing a library, every language with an FFI can trivially access a library written in C. Even without an FFI, most languages can interface with C code through some kind of bindings (like the Lua-C API, for example). Again, choosing C is a path to wide adoption.

Again, I don't particularly like C as a language. However, right now, it has an undeniable advantage as a platform. I do like Rust, however, and I would love to see Rust give C the boot. In order to do that, it needs to eventually (one day when the rate of additions/changes to the language has slowed and it has grown more stable/mature) offer a platform that can be relied on to "just work" on any given platform with minimal fuss and without any sudden changes. As such, both the "end-programmer" and the compiler-writer in me would like to see some version of Rust (again, eventually) that is "set in stone" and widely available, which really would solidify that notion of stability/maturity.

I'm not advocating for Rust to stop innovating. For all I care, the "standard" can be a simple snapshot of some state of the language, the way the Haskell Reports seem to be nowadays: GHC keeps on iterating and innovating the language, yet there's still a standard updated every x years that provides a static target. But for that designated snapshot, I want to see a compiler (or two, or several) and a bunch of libraries that are supported for the long haul.

It's simply a matter of "C has this, it's an important property thereof, and any replacement will need it, too".

[1]: Some other projects demand C because they constitute contributions or extensions of other projects that are already written in C; e.g., kernel code for an existing OS that is written in C.

Re:Rust vs C Pitfalls by blub on Wednesday December 28, 2016 @07:06AM (#13269995)
When Rust (or Swift or golang) gets ISO standardized we'll know that it's mature and left the "move fast and break things" phase. This won't happen, because it's still growing now, so it doesn't make sense to standardize. They might even always want to be able to move fast. I don't see golang ever being standardized.

The fact that someone says on HN "we're backwards compatible" doesn't quite offer the same level of trust as an ISO standard. Especially when there are some conflicting reports out there i.e. there are many super-awesome libraries that only work with nightly (I think it's called), because many of those maintainers are early adopters that love to try out new features.

Programming languages and libraries are building blocks, I don't want them to change under me in the middle of a project. This is why I dropped Swift, the 1.0 -> 2.0 migration was a very painful, and from what I hear recent major version changes aren't running smooth either.

Re:Rust vs C Pitfalls by tatterdemalion on Wednesday December 28, 2016 @12:35PM (#13272069)
> Especially when there are some conflicting reports out there i.e. there are many super-awesome libraries that only work with nightly (I think it's called), because many of those maintainers are early adopters that love to try out new features.

This is totally orthogonal to whether or not Rust stable is backward compatible, which it is. People put a lot of work into making sure it is, and this sort of FUD is very frustrating to read.

Re:Rust vs C Pitfalls by mmstick on Wednesday December 28, 2016 @02:18PM (#13272850)
> The fact that someone says on HN "we're backwards compatible" doesn't quite offer the same level of trust as an ISO standard.

Then you shouldn't take the word of a random person but from the Semantic Versioning guidelines. If you're not following the semantic versioning guidelines then you're doing it wrong.

http://semver.org/

> Especially when there are some conflicting reports out there i.e. there are many super-awesome libraries that only work with nightly (I think it's called), because many of those maintainers are early adopters that love to try out new features.

Totally irrelevant. Very few libraries, if any, require a nightly compiler. The libraries that do offer features that require a nightly compiler have those features as optional. Anyway, once the new Macros update releases, the need for that nightly compiler will go away. These libraries are just taking advantage of compiler plugins.

Re:Rust vs C Pitfalls by steveklabnik on Tuesday December 27, 2016 @07:59PM (#13267646)
There's at least two alternate compilers I know of in the works. We'll see when they're in a workable state, or at least, enough to compile rustc.

> In the meantime, I'd settle for an "LTS" release or something. That could work.

This is something we've discussed. I imagine it will happen. At first, I would expect six month LTSes, then longer ones as time goes on.

Re:Rust vs C Pitfalls by groovy2shoes on Wednesday December 28, 2016 @05:11AM (#13269615)
I could definitely live with such a solution, but even six months might be too quick. So, as long as the plan is to lengthen the LTS window, I think that could work.

The company that employs me just upgraded to a C++11-capable version of GCC three months ago. Even C++'s three year cadence seems like it might be too fast! Thing is, the company wants to vet our entire platform, which itself only changes yearly. They want to know they can get bug fixes, and vetting/upgrading the compiler is a lot of work regardless, so they tend to do one and stick with it for a while. OpenBSD does the same thing for security reasons. If Rust wants to replace C and/or C++, these are things that will need consideration eventually. I don't see my company allowing Rust any time soon, unfortunately.

As a compiler-writer, I'm more concerned that Rust is a quickly-moving target at the moment. I think that as Rust becomes more mature, it will naturally begin to stabilize feature-wise, in which case something akin to the Haskell model would work well, with innovation happening in the flagship compiler and "snapshots" of the language being taken as standards periodically. That's just a matter of time, though.

Re:Rust vs C Pitfalls by blub on Wednesday December 28, 2016 @07:14AM (#13270015)
Completely agree, C++'s three year cadence is probably the fastest more conservative industries are willing to go.

And why should one invest time for such a low-level component in their toolkit every 6 months?! I want to build software and solve problems, not spend my time keeping up with programming languages and library updates.

Re:Rust vs C Pitfalls by tatterdemalion on Wednesday December 28, 2016 @12:44PM (#13272126)
I have upgraded Rust every six weeks. I run `rustup update stable` and wait a minute. Its not a time investment! Rust puts so much work into guaranteeing backwards compatibility so that updating every 6 weeks is an effortless process.

You seem to come from an experience where software updates are kinda sorta mostly backwards compatible. Rust works very hard to actually be backwards compatible. There is infrastructure to check for regressions across the entire package ecosystem, which is run regularly on HEAD and on any commit we think might potentially be breaking before we even land it.

Re:Rust vs C Pitfalls by naasking on Wednesday December 28, 2016 @01:03AM (#13268756)
> Meanwhile, C code from the mid-80s still compiles with modern compilers, often without any changes whatsoever, and without any feature gates.

You say that like it's a good thing that with C, you can ignore 30 years of progress in software development. Colour me unconvinced.

Re:Rust vs C Pitfalls by grzm on Wednesday December 28, 2016 @01:11AM (#13268775)
If the software does what you want, being able to run on 30 years worth of hardware with just a recompile is a good thing. At the end of the day, it's what the software does that's important.
Re:Rust vs C Pitfalls by naasking on Wednesday December 28, 2016 @01:22AM (#13268812)
> If the software does what you want, being able to run on 30 years worth of hardware with just a recompile is a good thing

That's not a responsible metric. 30 year old software was written against 30 year old APIs vulnerable to known attack vectors, and with 30 year old notions about security. The belief that this software is suitable for modern use is absurd IMO.

And if the types of programs you're talking about are small UNIX-like utilities, well then they're small and easily updated aren't they?

Re:Rust vs C Pitfalls by groovy2shoes on Wednesday December 28, 2016 @05:23AM (#13269659)
More often than not, brand-spanking-new software is written against 30-year-old APIs.

Lots of software we use day-to-day is old. For example, a couple years ago I fixed a 20-year-old bug in netcat, which itself hadn't been updated since the mid 90s. After I fixed the bug, I didn't need to fish out an old compiler or any compatibility libraries; I just compiled it with the latest GCC and glibc, and carried on with my day.

Don't get me wrong, I like Rust a lot and I'm excited that there's finally a real contender for the systems programming throne after all these years. I'm just less enthused about the prospect of refactoring my codebase once every few months to stay current. This is something that I think will level out with time, though. C itself was almost 20 years old before it was standardized, after all. I don't think it will take Rust that long, and I look forward to the day my copy of the Rust standard arrives on my doorstep.

Re:Rust vs C Pitfalls by naasking on Wednesday December 28, 2016 @09:30AM (#13270669)
> More often than not, brand-spanking-new software is written against 30-year-old APIs.

Let's assume this is true, brand-spanking new software will be written against 30 year old APIs that have survived 30 years of attacks and audits, but will avoid the ones that have proven vulnerable.

> I'm just less enthused about the prospect of refactoring my codebase once every few months to stay current.

The perception that you need to do this is false. You might feel pressured to refactor simply because of new syntactic improvements that make code clearer (like switching try!() macro to infix ?), but that pressure is a fiction. There's no real need to do it.

Re:Rust vs C Pitfalls by dikaiosune on Wednesday December 28, 2016 @12:47PM (#13272155)
> After I fixed the bug, I didn't need to fish out an old compiler or any compatibility libraries; I just compiled it with the latest GCC and glibc, and carried on with my day.

Could you show me an example where post-1.0 you wouldn't be able to do this with Rust?

Re:Rust vs C Pitfalls by grzm on Wednesday December 28, 2016 @01:26AM (#13268834)
If the software does what you want includes all of those criteria. If you find that there are deficiencies in any of those areas, that would qualify as a reason to make changes, weighed against the cost of doing so.
Re:Rust vs C Pitfalls by naasking on Wednesday December 28, 2016 @09:27AM (#13270647)
> If the software does what you want includes all of those criteria.

Except most people don't consider those as criteria at all. The only criteria considered are "does it run and produce the output I want".

Re:Rust vs C Pitfalls by Manishearth on Wednesday December 28, 2016 @01:41AM (#13268876)
And the plan is that you'll be able to do the same with Rust; the more rapid release strategy doesn't affect that at all.

What the rapid releases do affect is the rate at which new releases of libraries stop working on older compilers, which absolutely has to do with ignoring progress.

Re:Rust vs C Pitfalls by erikpukinskis on Wednesday December 28, 2016 @11:08AM (#13271381)
This is my same problem with JavaScript. Yes it's wonderful that changes are backwards compatible. But if the entire community is updating libraries you rely on to use new language features then you have no choice but to use those features too.

Or stop using other peoples' code and just use core language features and build everything from scratch. Which is what I end up doing, and it has some benefits. But it definitely slows you down.

Re:Rust vs C Pitfalls by Manishearth on Tuesday December 27, 2016 @11:23PM (#13268397)
Not everyone uses C only for the cases when they need a "small and portable language". C is used quite a bit in places where Rust or C++ would do fine too, for various reasons. That's where you want to compare them.
Re:Rust vs C Pitfalls by zzzcpan on Tuesday December 27, 2016 @05:48PM (#13266911)
Maybe Rust folks should make their own C backend for better integration with C compilers and have that portability, since LLVM folks decided to abandon theirs.
Re:Rust vs C Pitfalls by Ericson2314 on Tuesday December 27, 2016 @11:47PM (#13268458)
libc is very hard to use portably