Please don't write programs in bare C. Use Go if you're looking for something very simple and fast-enough for most uses; it's even memory safe as long as you avoid shared-state concurrency.
Unqualified "fast enough" is pretty much exactly the problem being pointed out. Most developers have no idea what "fast" is let alone "fast enough". If they were taught to benchmark at with a lower level language, see what adding different abstractions causes, that would help a ton.
I would personally suggest C++ though because there is such a huge amount of knowledge around performance and abstraction in that community - wonderful conference talks and blog posts to learn from.
Go comes from a different school of compiler design where the code generation is decent in most cases, but struggles with calculations and more specific patterns. Delphi is a similar compiler. Looking at benchmarks, the performance is only a few times worse than optimized C. That's on par with the most optimized JITed languages like Java, while being overall a much simpler compiler. I feel it is is fair to say 'good enough' in this situation.
It's not an "unqualified" claim, Go really is fast enough compared to the likes of Python and Ruby. I'm not saying that rewriting a Go program in a faster language (C/C++/Rust) can't sometimes be effective, but that's due to special circumstances - it's not something that generalizes to any and all programs.
You've obviously been burned by null pointers (probably not just once). And you think they are a problem, and you're right. And you think they are a mistake, and you could be right about that, too.
But they're not the only problem. Writing async network servers can be a problem, too. Go helps a lot with that problem. If for your situation it helps more with that than it hurts with nulls, then it can be a rational choice.
And, don't assume that go must be a bad choice for all programmers, in all situations. It's not.
Nothing wrong with any of these languages, especially C. It's been around since the early 70s and is not going anywhere. There's a very good reason it (and to an extent C++) is still is the default language for doing a lot of things since everyone understands it.
C and C++ both have excellent library support, perhaps the best interop of any language out there and platform support that cannot be beat.
That said, they're also challenging to use for the "average" (median) developer who'd end up creating code that is error-prone and would probably have memory leaks sooner or later.
Thus, unless you have a good reason (of which, admittedly, there are plenty) to use C or C++, something that holds your hand a bit more might be a reasonable choice for many people out there.
Go is a decent choice, because of a fairly shallow learning curve and not too much complexity, while having good library support and decent platform support.
Rust is a safer choice, but at the expense of needing to spend a non-insignificant amount of time learning the language, even though the compiler is pretty good at being helpful too.
> That said, they're also challenging to use for the "average" (median) developer who'd end up creating code that is error-prone and would probably have memory leaks sooner or later.
Many of the most highly credentialed, veteran C developers have said they can't write secure C code. Food for thought.
> Go is a decent choice, because of a fairly shallow learning curve and not too much complexity, while having good library support and decent platform support. Rust is a safer choice, but at the expense of needing to spend a non-insignificant amount of time learning the language, even though the compiler is pretty good at being helpful too.
Go doesn't have the strongest static guarantees, but it does provide a decent amount of static guarantees while also keeping the iteration cycle to a minimum. Languages like Rust have significantly longer iteration cycles, such that you can very likely ship sooner with Go at similar quality levels (time savings can go into catching bugs, including bugs which Rust's static analysis can't catch, such as race conditions). Moreover, I've had a few experiences where I got so in-the-weeds trying to pacify Rust's borrow-checker that I overlooked relatively straightforward bugs that I almost certainly would've caught in a less-tedious languages--sometimes static analysis can be distracting and in that respect, harm quality (I don't think this a big effect, but it's not something I've seen much discussion about).
There is unsecure code hidden in every project that uses any programming language ;)
I get what you're saying here, you're specifically talking about security vulnerabilities from memory related errors. I honestly wonder how many of these security vulnerabilities are truly issues that never would have come up in a more "secure" language like Java, or if the vulnerabilities would have just surfaced in a different manner.
In other words, we're constantly told C and C++ are unsafe languages they should never be used and blah blah blah. How much of this is because of the fact that C has been around since the 1970s, so its had a lot more time to rack up large apps with security vulnerabilities, whereas most of the new recommended languages to replace C and C++ have been around since the late 90s. In another 20 years will we be saying the same thing about java that people say about C and C++? And will we be telling people to switch to the latest and greatest because Java is "unsafe"? Are these errors due to the language, or is it because we will always have attackers looking for vulnerabilities that will always exist because programmers are fallible and write buggy code?
> In another 20 years will we be saying the same thing about java that people say about C and C++? And will we be telling people to switch to the latest and greatest because Java is "unsafe"?
As long as the vulnerability types that cause trouble in language B are a superset of those that cause trouble in language C, it makes sense to recommend moving from B to C for safety reasons.
This is true even if there is a language A that is even worse and in the absence of language C, we recommended moving from A to B. Code written in A will be worse in expectation than code written in B than code written in C.
> I honestly wonder how many of these security vulnerabilities are truly issues that never would have come up in a more "secure" language like Java, or if the vulnerabilities would have just surfaced in a different manner.
Memory safety vulnerabilities basically boil down to following causes: null pointer dereferences, use-after-free (/dangling stack pointers), uninitialized memory, array out-of-bounds, and type confusion. Now, strictly speaking, in a memory-safe languages, you're guaranteed not to get uncontrollable behavior in any of these cases, but if the result is a thrown exception or panic or similar, your program is still crashing. And I think for your purposes, such a crash isn't meaningfully better than C's well-things-are-going-haywire.
That said, use-after-free and uninitialized memory vulnerabilities are completely impossible in a GC language--you're not going to even get a controlled crash. In a language like Rust or even C++ in some cases, these issues are effectively mitigated to the point where I'm able to trust that it's not the cause of anything I'm seeing. Null-pointer dereferences are not effectively mitigated against in Java, but in Rust (which has nullability as part of the type), it does end up being effectively mitigated. This does leave out-of-bounds and type confusion as two errors that are not effectively mitigated by even safe languages, although they might end up being safer in practice.
It depends on what you mean by mitigated. Java mitigates null pointers by deterministically raising an exception (as well as out of range situations), but indeed it doesn’t handle them at compile time (though the latter can’t even be solved in the general case, and only with dependent types)
> There is unsecure code hidden in every project that uses any programming language ;)
Security isn't a binary :) Two insecure code bases can have different degrees of insecurity.
> I honestly wonder how many of these security vulnerabilities are truly issues that never would have come up in a more "secure" language like Java, or if the vulnerabilities would have just surfaced in a different manner.
I don't know how memory safety vulns could manifest differently in Java or Rust.
> In other words, we're constantly told C and C++ are unsafe languages they should never be used and blah blah blah. How much of this is because of the fact that C has been around since the 1970s, so its had a lot more time to rack up large apps with security vulnerabilities
That doesn't address the veteran C programmers who say they can't reliably write secure C code (that's new code, not 50 year old code).
> Are these errors due to the language, or is it because we will always have attackers looking for vulnerabilities that will always exist because programmers are fallible and write buggy code?
A memory safe language can't have memory safety vulnerabilities (of course, most "memory safe" languages have the ability to opt out of memory safety for certain small sections, and maybe 0.5% of code written in these languages is memory-unsafe, but that's still a whole lot less than the ~100% of C and C++ code).
Of course, there are other classes of errors that Java, Rust, Go, etc can't preclude with much more efficacy than C or C++, but eliminating entire classes of vulnerabilities is a pretty compelling reason to avoid C and C++ for a whole lot of code if one can help it (and increasingly one can help it).
First of all, you’re comparing “most PHP and JS programmers” with veteran C programmers, and secondly most PHP and JS programmers can write code which is secure against memory-based exploits.
It is easier to just pick an existing library and deal with security flaws, than trying to ramp up an ecosystem from scratch, unless one has the backing of a multinational pumping up development.
Yes. For some reason programming culture repeatedly fails to realise that if you want to group languages into two buckets by performance with one being "like C" and the other being "like Python" then all the languages you list (except maybe JS) belong in the "like C" bucket.
I mean, he just explained that after rewriting his program in Dart, it was fast enough? That's not really the point here.
On the other hand, I tried writing a Wren interpreter in Go and it was considerably slower than the C version. Even programming languages that are usually pretty fast aren't always fast, and interpreter inner loops are a weak spot for Go.
> I mean, he just explained that after rewriting his program in Dart, it was fast enough?
Yes, and that makes his C advocacy even less sensible. Dart is a perfectly fine language, even though it seems to be a bit underused compared to others.
I didn't advocate that anyone ship production code written in C.
I advocated that people write programs in C and run them to see how fast executables can startup and run.
(Dart isn't great for that because while its runtime performance is pretty fantastic, it does still take a hit on startup because it's a VM with a fairly large core library and runtime system.)
Spending "a little time writing some programs in C" is not the same as advocating that people write most of their code in C, or that you use it in production.
Maybe try reading Crafting Interpreters, half of which is in Java and half in C.