10 ms·
Unless he means that Rust should be used on projects where the Rust compiler is available for all relevant platforms and C and C++ can be used otherwise, I disa
by ghoward 4y ago
Unless he means that Rust should be used on projects where the Rust compiler is available for all relevant platforms and C and C++ can be used otherwise, I disagree.
In fact, until LLVM is replaced, C++ will probably be the language of choice for new languages. Even `rustc` requires a C++ bootstrap for that purpose.
There are also other important C++ and C libraries that will continue to mean C and C++ may be better choices than Rust in certain cases.
And don't get me started on embedded.
Also, that doesn't even matter when the purpose is a hobby project (such as mine) where the programmer has no interest in Rust (such as me).
I like how Trevor Jim put it [1] better:
> If you decide to write your project in C/C++ you must have a plan for handling the inevitable memory corruption in advance. Anything else is malpractice.
This is possible to do. I've released a non-trivial program that has had no known memory bugs ever since 1.0 on 2018-10-26. It is written in C. And I challenge anyone to find one in any release since then. You might find one, but I think it will be tough.
In other words, it's possible to put C and C++ on the same footing as Rust when it comes to memory bugs; after all, even Rust is not perfect there.
Yes, it takes more effort. A lot more effort. For my hobby projects, that works fine because I'd rather work in C with the extra effort than in Rust.
Oh, and it's possible to make C as good as Rust: I've got macros to do automatic bounds checking. I've got RAII and stack traces. I've got structured concurrency, which will give the same capabilities as the Rust borrow checker if you adjust your coding style. And all this in portable C11.
So no, Rust is not the end-all be-all of languages. Sorry.
Rant about absolutist opinion over.
But seriously, use Rust if it's available for your target platforms, and you have no other preference.
[1]: http://trevorjim.com/using-an-unsafe-language-is-a-design-flaw/ http://trevorjim.com/using-an-unsafe-language-is-a-design-fl...
- customkitchen 4y agoIf we are offering absolutist opinions, I would like to offer a counterpoint. >I've got macros to do automatic bounds checking. I've got RAII and stack traces. I've got structured concurrency, which will give the same capabilities as the Rust borrow checker if you adjust your coding style. And all this in portable C11. You can do this all in C but it is an absolute nightmare. Every large C program grows some strange bespoke and incompatible versions of all that stuff at some point. And they're all a pain to use because none of it is idiomatic to the language. It's seriously awful. Things like the Linux kernel are the worst offenders. I will be happy when the C language finally reaches the end of its miserable, slow, agonizing death.
- ghoward 4y agoI understand you think it's awful, but I do like it. Everyone has their preference.
- customkitchen 4y agoYou can like something and still admit that it is awful. I "liked" C for a long time before there were better options...
- ghoward 4y agoI still disagree that it's awful.
- bravura 4y agoThe argument you are missing: Your position is bespoke and incompatible. You don't use idioms in your C code. You use idiolect. Thus, you exist in your own universe and are a party of one. And the clue was something you might not expect... I programmed C++ for five years, and C for over ten years before that. I don't know rust, but I followed this discussion with great interest. One of the topics that came up several times was being able to identify who wrote what C++ code based upon their choice of language subset without using blame. In the pro-rust arguments and C++ counter-arguments and rust counter-counter-arguments and C++ counter-counter-counter arguments in discussions above yours, I was pleasantly surprised to see that grandfather comments were rarely (never?) the same author. At least the rust and C++ arguments were made by different people sharing some sort of group mentality. Then I hit your thread and saw the grandchild comment: "I understand you think it's awful, but I do like it. Everyone has their preference." and I was like: "Okay. I bet grandparent is also ghoward." The simple fact that no one is chiming in to grandchild your arguments is the point that you're missing. In fact, the entire subthreads you've spawned involve basically ghoward defending ghoward's position. It's nice when other people can take over your work. That's what we're after.
- 4y ago
- synergy20 4y ago"Oh, and it's possible to make C as good as Rust", do you have some concrete advice documented somewhere? Thanks!
- mmis1000 4y agoProbably write it in Rust first and make a direct C port based on it? (Or is there a tool do this automatically already?)
- unrealhoang 4y agoYes, mrustc is a compiler that compile Rust into C code.
- gavinhoward 4y agoI hate to admit this, but it took me a long time to do, mostly because I was not experienced when I started writing code, and the code has been rewritten several times over to get it right. First off is the code in [1]. It's technically under several licenses, but I can give it to you under the public domain because bounds checking in C is important enough that I'll give it away. The `y_ARRAY_TYPE()` macro generates a struct that is an array with bounds. Use it like this: typedef y_ARRAY_TYPE(uint32_t) uint32_t_arr; `uint32_t_arr` is a bounded array of `uint32_t`'s. You can then pass that array to functions and do bounds checks with the `y_i()` macro (for when the struct value is not a pointer) and the `y_ip()` macro (for when the struct value is a pointer). To implement RAII, the code to do that is in the same repo, but it's...much more complicated: a full stack allocator. I just add the destructor as a parameter when allocating memory, and when the allocation is freed, the destructor is called when it's non-NULL. Then there are functions to allocate and free, but it is always done in a stack, to emulate the real stack. By the way, the type of destructor is void (*y_Destructor)(void*) and it takes a pointer to the item to be destroyed. Structured concurrency takes the idea of a thread-local stack and sort of generalizes it across threads. The idea is that each thread has a parent, and that parent is not joined until all of its child threads are joined. All threads form a tree, almost exactly like process trees in Linux. This means that if you want to have another thread borrow an item, you just have to make sure that thread is a descendant of the thread it is borrowing the item from, and you have a guarantee that the item will never go out of scope before the borrowing thread does. Sometimes you need to change your code to do that. You can "push" things "down the stack" by passing function pointer callbacks to callees who then create the item to borrow and call the callbacks. Inside the callbacks, the borrowed item will always exist. There's more to it than that (you can turn a thread tree into a DAG [2], allowing you to turn threads that are not descendants of a thread into descendants), but that's probably good enough to start you off. [1]: https://git.yzena.com/Yzena/Yc/src/commit/cf4c96b3560d/include/yc/array.h https://git.yzena.com/Yzena/Yc/src/commit/cf4c96b3560d/inclu... [2]: https://lobste.rs/s/8msejg/notes_on_structured_concurrency_go#c_wkxbvb https://lobste.rs/s/8msejg/notes_on_structured_concurrency_g...
- drivebycomment 4y ago> In other words, it's possible to put C and C++ on the same footing as Rust when it comes to memory bugs; No. This is only true if you don't care about occasional bugs. e.g. hobby projects. But if you're talking about mission-critical or security-critical software, there is a gap - or a canyon - between C vs C++ vs Rust. And no amount of extra "efforts" by the programmer's part can bridge those gaps completely.
- ghoward 4y agoThe true test of what I said is "show me the code." The code is my `bc`. [1] Find a memory bug, any memory bug, in my `bc` after 1.0. Rust has occasional memory bugs too; I mentioned that specifically. It still happens. So if you really are correct, break my `bc`. [1]: https://git.yzena.com/gavin/bc https://git.yzena.com/gavin/bc
- stouset 4y agoYes, let’s ignore the quite literally millions of examples of prior art for memory bugs in C/C++ programs because you believe you’ve managed to build a single-threaded CLI calculator that doesn’t have any. I know how to call `strcpy` safely. Are we clear to put that back into the Linux kernel then?
- ghoward 4y agoNotice that in my first post, I said to use Rust where practical. I never said that everyone should use C. I'm only claiming that I personally can do just as well in C as I could do in Rust, and that I prefer to work in C, so I might as well. Break my `bc`.
- stouset 4y agoI honestly don't understand the point of your post then. Are you looking for a pat on the back?
- 4y ago
- howinteresting 4y agoNo one's talking about your personal project here. The audience is teams of people building software to be used in production.
- 1500100900 4y agoGavin's personal project is being used in production.
- ghoward 4y agoExcept that the tweet was pretty absolute. He could have had a reply tweet with something like "unless you have to or you're doing a hobby project." I took issue with the absolutism.
- bowlerman 4y agoThose qualifications are going to hold for any advice about technology. You can even justify using malbolge for your hobby project with "I like it" or "It's just for fun". If your company is only going to pay you for producing malbolge code, then you write malbolge or quit. If you decide to stay, then trying to change their mind might be a good idea if you can spare the effort.
- ghoward 4y ago> Those qualifications are going to hold for any advice about technology. They should hold, but the RESF can be too absolutist. The wording of the tweet encouraged that, so I was just trying to push back on it.
- alkonaut 4y ago> Oh, and it's possible to make C as good as Rust: I've got macros to do automatic bounds checking. The really tricky macro though comes when you want to check races in shared mutable state...
- ghoward 4y agoNo macros. This is one spot where Rust is better than C. (Though it is too limiting for my taste.) Instead, I use ThreadSanitizer and add locks where I may not even need them. Then I may remove some, or change them to different synchronization primitives, and between every change, run TSan several hundred of thousands of times to tease out any race conditions. It's my way of fuzzing for race conditions.