Death to C, ++
techcrunch.com
techcrunch.com
That said, if you are writing something new, you should carefully consider whether C is the best choice before using it. If you are working within a nearly-impossible-to-replace + enormous codebase (such as the Linux kernel), it is the only option. If your project's #1 goal is performance above all else, and you are a seasoned or aspiring expert, perhaps C is the best choice. The majority of people writing software do not fall into either of these categories.
1. header-only library 2. compiled library 3. compiled library with type framework 4. framework 5. meta-programming framework 6. custom meta-programming framework 7. domain specific language 8. custom domain specific language 9. generic programming language 10. custom generic programming language
As a side note, increase in complexity also might increase job security of a developer. If you are after it, design your own programming language and try to deliver every project implemented in it :) Should your projects be in high demand, your skills will be in high demand as well!
There are many reasons to move from an older language to a newer one. There are good reasons, and there are bad reasons. I think language designers and evangelists generally do a good job of focusing on the good reasons. It's unfortunate when such advocacy tips over into FUD, but I suppose it's inevitable too. Nobody likes to see their investment devalued because their favorite vehicle to fame and glory lost out, even if the alternative really was even better.
I think younger programmers' frustrations with old, difficult (and sometimes useful) tools along with their drive to modernize everything occasionally drives them to misdiagnose something as "legacy bullshit that isn't user-oriented enough" vs. "a powerful tool which is still necessary with limited uses".
I think C is a great language. I also think Rust is great but I would not bash one against the other.
This kind of evangelism is unproductive in my opinion.
I do think Rust is a viable replacement for C, but not a replacement for modern C++, rather an alternative - at least for the foreseeable future.
Which you are, because "this" is a raw pointer. The same applies to references and iterators, which are used everywhere. It's not feasible to use C++ without using those features.
Besides, you can get UAF without any references at all. Read/write races on a vector, for example.
I went to college less than 20 years ago where I used plenty of C++ and I've had multiple jobs since then using it (my current work is in Scala). I have no idea how to work in Modern C++ and I'm pretty confident it would take longer for me to learn than Rust.
I see the attitude to C as analogous to PHP in the web programming sphere. Everyone complains about PHP. And yet despite all the criticism to avoid PHP, the overwhelming majority of server-side web apps are written in PHP. Not Python or Ruby or Lua or some other language. Some estimates state PHP makes up 80% of server-side web code.
Why haven't these other languages displaced PHP? Because none of them can match PHPs simplicity and ease of deployment. Not Python or Ruby or Lua or any other language.
And of what of C? It's a similar scenario. Where is the fast, strongly-typed, low-memory programming language with a friendly readable syntax for low and high-level programming? Does it exist? Is Rust that language?
There is a famous quote by B. Stroustrup about this phenomenon.
[1] https://github.com/faragon/libsrt/blob/master/doc/benchmarks...
It took me a while to "get" Rust, but I'm now much productive in it than C. Syntax is not pretty, but it's convenient.
Now whenever I program in C I miss being able to declare which pointers are owned/borrowed (and great dependency management, etc., etc.)
The only thing I miss from C is its wide acceptance. I have to justify use of Rust, but not use of autotools :O
And with that, the safety of Rust is (IMO) overstated - the distinction between `unsafe` and `safe` is not a very good way to judge safety. I wrote a lot about this here[0].
All that said though, there are also lots of things I liked about Rust. In particular I found slices to be something I really wish was in C, they basically just solidify the normal way you do things in C, and it then allows the compiler do things like bounds checking. The `enum` system is also fairly nice.
[0] https://www.reddit.com/r/programming/comments/6f235k/rewrite...
All the fancy features sound nice, but the moment you try something large and non trivial all sorts of hacks seep into your codebase.
The solution is the same as in C++, write straightforward code and avoid terseness. But if you are at that level already you could just use C++ for a much more mature toolchain (blows away rust when it comes to compiler optimizations even when both use an LLVM backend).
Personally, the safety aspects of rust have never been problems for me. Two biggest problems I've had developing in C/C++ over the years are A) compiler inconsistencies, B) API inconsistencies, and B isn't really C's fault. I can kind of see why Javascript is so popular--with Chrome and Node using V8, that's one less battle you have to fight.
Another bittwiddler++ language is just digging the hole deeper.
I learned to program in C, during the dawn of the Internet. Yes, the "I can do anything on the machine" power was fun.
But when considering all C/C++ code is completely insecure by default, it really shouldn't be used to build anything new that processes untrusted input (which is just about everything). There are a few decades worth of mature alternatives that should be considered first, plus a few newcomers like Rust and golang.
When someone goes on about how Rust's weak "guarantees"[0] on memory safety and data races are going to make code "secure," I don't know how to politely respond to that level of delusion.
[0] 'unsafe' blocks and the non-Rust world everything has to tie-into
auto v = vector<int> { 1, 2, 3 };
auto &e = v[0]; // plan to use element later
// ...
v.push_back(v.size());
// ...
cout << e << "\n"; // boom
As a real example of this: suppose you're managing a vector of connected users. v is large enough to hold 64 user structs. e is a reference to the last user who produced an event. If a 65th user connects then the vector will need to be reallocated, thereby invalidating e.Rust saves you here. The compiler will let you have a reference to the element if the vector is marked as immutable. If the vector is marked as mutable the compiler will yell at you and you'll need to store an index instead.
So, mark it as const here and see the same effect?
c++ will let you push_back while holding a reference to an element of that vector. rust will not.
So, if you have a const reference, you can't make this mistake in it's entirety, but you can certainly make the mistake of keeping a reference to something you got through a const pointer.
Also, marking as const is something you have to opt-in to, and there is still disagreement on the value of const.
That is the point of C++, things other languages do at a language level you can easily design as a library without paying a cost if you do not use it.
You do not pay a performance cost for borrowing semantics in rust.
Which is precisely what Rust does.
#include "msemstdvector.h"
// ...
auto v = mse::mstd::vector<int> { 1, 2, 3 };
auto e = v.begin() + 0; // 'e' is a safe iterator here
// ...
v.push_back(v.size());
// ...
cout << *e << "\n"; // no problem
Not much different from your original code.Rust's policy of static enforcement of "exclusive mutable references" still might be preferable in many cases, but there is a practical option of using C++ in a safe(r) way.
I love the language but this kind of shallow patronising is ridiculous and it doesn't serve Rust. It's not good for anybody. Rust can do (and does) better without it.
2. Modern C++ is so zero-overhead template and otherwise compile-time obsessed language. Yes it can be productive, somewhat safer than C, but the language is so terribly complicated, that it really misses the point imo.
3. Rust is modern low-level language with safety agenda and zero-overhead abstractions. The type system is still hard to master. Guess this one fits low-level system programming very well.
4. We really need a low-level productive modern language with just a 'convenience' level of safety, but high degree of control over low level performance: simd, alignment, atomics, cache levels etc.
I haven't seen a C/C++ programmer who doesn't need that.
Really?
Amazing.
Over time many protections have been put in place to help mitigate against native bugs like DEP, stack cookies and ASLR. While not full proof, they make these attack vectors a lot more difficult and who knows, maybe we'll start seeing fully position independent code for all system libraries making it even more difficult.
I really need to check out Rust though and see what all the hype is about :)
This could probably apply to anything, including a language itself.
Better by what metric? The quote seems to suggest that the only metric is how "dangerous" something is, but in the real world that's just one of many trade-offs we must make. What about performance, instrumentation and debugging features, complexity of implementation, etc.
One imagines room for quite a lot of nuance in interpreting this recommendation.
I spent a lot of time programming in Turbo Pascal, and C has always looked like a major downgrade to me. No modules, insufficient type checking, and the build system is a completely separate step with its own languages brought in (arcane command line, makefiles, project files...).
Wrong. For example I cannot easily use a C++ framework from Rust. As bindgen and other bridge approaches get better, I have hope, but to say it is a viable replacement right now is just false.
Rust is very serious about declaring library interfaces reliably. It's leaning towards explicit over magic, early type errors rather than errors at substitution or runtime, so there is a bit of ceremony in function declarations, especially with generics (but then they work without having to put them in headers :)
OTOH type inference, automatic-ish memory management, everything-is-an-expression, and a lot of ergonomic help around error handling make up for it.
And I really appreciate the uniform enforcement, because I write bugs exactly where I don't expect to write them.
Unfortunately I know of literally no large-scale project worked on by a large team using industry-standard practices (i.e. not NASA levels of verification, which are economically unviable for most software) that has consistently written correct C++.
You can easily find examples for correctness modulo errors Rust would have prevented.