
Death to C - simas
http://techcrunch.com/2015/05/02/and-c-plus-plus-too
======
vezzy-fnord
I think what a lot of people don't realize is that, at least if you're writing
Unix userspace code that mostly interacts with POSIX and/or kernel-specific
interfaces, C remains the most convenient because the API/ABI standards are
all designed with C semantics in mind, and a lot of wrapper/binding libraries
in other languages are either too clunky or too abstracted, unless you decide
to roll your own... and depending on the language, FFIs can be quite a
nuisance.

The only languages so far that seem to have really gotten this are Go... and
OCaml, to some extent (see the "Unix system programming in OCaml" document).
Go in particular bypasses libc entirely by directly using the syscall
interface, from what I recall.

~~~
jjoonathan
> FFIs can be quite a nuisance

Understatement. Every time I've tried to use a FFI I ran into either a show-
stopping bug or a show-stopping feature limitation. My first few open-source
contributions were patches for these bugs, as it happens, but the whole
process was a massive slog that ended in repeated failure. I now loathe them
with a passion.

Still, this all happened before LLVM-languages came around. Maybe things are
better now. I look forward to the next time I have to use a FFI with both hope
and fear.

> Go in particular bypasses libc entirely by directly using the syscall
> interface

That's nifty, but a big chunk of the reason for having C compatibility is that
many higher-level libraries are written in it. How easy is it to talk to,
e.g., the window manager using raw syscalls?

------
jblow
The problems described are accurate. From a modern standpoint, C and C++ are
terrible. The only problem is that most new languages are more terrible along
other axes, making them unusable for what C and C++ get used for.

The author is accurate that Rust may be a substantial improvement.

I don't necessarily want to program in Rust, which is why I am designing my
own alternative, but I think if you are building safety-critical software than
something Rust-like is a pretty good idea.

For my own experiments I am going more in the direction of giving the
programmer auditing power, rather than just having the programmer have to
silently worry about what code may or may not be doing.

------
ColinWright
Extensive discussion:
[https://news.ycombinator.com/item?id=9477006](https://news.ycombinator.com/item?id=9477006)

Nice to see all the same arguments from just 4 hours ago being repeated again
here.

------
Yetanfou
I'm almost tempted to pull out the old adage "if you can't stand the heat, get
out of the kitchen". Yes, the C family of languages allows you to do many
terrible things. It also allows you to do many great things. It is up to the
programmer to decide what path to choose.

While the appropriate territory for the C family has decreased with the
increase in processing capacity, there are still many areas where these
languages are the right tool for the job. When another language family finally
arises which offers the flexibility, conciseness and low-level access which
characterises C (and its siblings, to a lesser extent) it'll be welcomed as a
saviour, until that time they're the right time for the job.

------
ddingus
Not gonna happen.

We need close to the metal tools for a whole pile of things, and that's not
going to change.

If anything, tools to help write C, or find errors, test, etc... are the more
likely path.

That said, we could reduce the number of use cases for C now, and not lose too
much, but that's not going to be the death of it by any means. More like a
rational pruning.

~~~
copsarebastards
> If anything, tools to help write C, or find errors, test, etc... are the
> more likely path.

Ugh, _as if_ we haven't been going down this path for three decades. We're
still getting shit like heartbleed. When can we admit that path doesn't work
and start trying other things?

~~~
xamuel
Heartbleed is a symptom of bad programming, not a bad language. C is "less
secure" because it allows the programmer to do possibly-unsafe things at their
own discretion. The alternative is to flat-out ban those things. Which is
appropriate for some use cases (the kind where performance doesn't matter).
Inappropriate for others (the kind where performance does matter).

~~~
copsarebastards
> Heartbleed is a symptom of bad programming, not a bad language.

Okay, so your claim is tantamount to "every major C program is badly
programmed", because every major C program has memory related bugs. If it's
really bad programming, not a bad language, why is it that C is so much more
often poorly programmed than, say, Python?

If it's C programmers, not the C language, then we should avoid C because
that's the easiest way to avoid these terrible C programmers.

> C is "less secure" because it allows the programmer to do possibly-unsafe
> things at their own discretion. The alternative is to flat-out ban those
> things.

That's not the only alternative, you're just ignorant of the alternatives.

~~~
xamuel
>why is it that C is so much more often poorly programmed than, say, Python?

It's kind of like saying: trauma surgeons must be more dangerous than
pediatricians, because so many more patients die in the care of a trauma
surgeon than in the care of a pediatrician. It ignores the fact that you
wouldn't send a pediatrician to such a difficult patient as you'd send a
trauma surgeon to. You wouldn't use Python in a lot of the places you'd use C
because the performance would be "shaggy puppy meets Godzilla" lousy.

>That's not the only alternative

Suppose I've established that the fastest way the computer can do X involves
having the CPU (which only knows machine code, no magical languages) access a
memory location without checking if it's in bounds. Either the language allows
me to program that, or it doesn't. If it does, then Heartbleed-like bugs are
possible. QED.

Alright, there's technically one other alternative, require the programmer to
formally proof-verify that the code does as it's supposed to. I hope that this
will become more practical within my daughter's lifetime (it probably won't
within mine).

~~~
copsarebastards
> It's kind of like saying: trauma surgeons must be more dangerous than
> pediatricians, because so many more patients die in the care of a trauma
> surgeon than in the care of a pediatrician. It ignores the fact that you
> wouldn't send a pediatrician to such a difficult patient as you'd send a
> trauma surgeon to. You wouldn't use Python in a lot of the places you'd use
> C because the performance would be "shaggy puppy meets Godzilla" lousy.

You can make any argument by analogy.

> Suppose I've established that the fastest way the computer can do X involves
> having the CPU (which only knows machine code, no magical languages) access
> a memory location without checking if it's in bounds. Either the language
> allows me to program that, or it doesn't. If it does, then Heartbleed-like
> bugs are possible. QED.

Suppose we don't suppose things that are wrong. Static type checking can check
bounds at no runtime cost this in many cases. Like I said, your argument is
based on ignorance of the alternatives.

> Alright, there's technically one other alternative, require the programmer
> to formally proof-verify that the code does as it's supposed to. I hope that
> this will become more practical within my daughter's lifetime (it probably
> won't within mine).

I'm not hoping for 100% formal verification here, I'm merely hoping to be
significantly better than C. That's a _very_ low bar: C does very little
checking. Why on earth would you be opposed to this?

In fact, I don't think we'll _ever_ be able to 100% formally verify that a
program does what it's supposed to. You can verify some things, like memory
access, but in the end we'll never be able to 100% verify that the thing we
are verifying is the desired behavior.

Look, I'm not criticizing the people who made C or the people who wrote tons
of code in C. C was a great language in its time. But it's literally 4 decades
old: it would be unreasonable to expect it to not show signs of age.

------
lukaslalinsky
Every time I look at it, I have a very hard time taking Rust seriously. I
really don't get whoever decided to use the shortest keyword names possible.
It looks like a nice alternative to C, but wrapped in a horrible syntax. fn,
f64, i32, u8, mut, mod, pub, ...

~~~
smosher_
You are probably experiencing a syntactic illusion where it looks like C++ but
then it looks all wrong. I've used Rust and it didn't take long to get
acclimated.

------
TYPE_FASTER
> Can we stop hand-writing parsing code in C please?

I think that tweet is more about using Lex or Yacc instead of hand-coding
logic to parse strings.

~~~
xamuel
Lex/Yacc are great for parsing things like your own internal files that the
end-user never directly touches. But if you really care about your users,
there are certain times when you've just gotta bite the bullet and hand-roll a
parser. Because when the user mis-places a punctuation mark, it's much better
to give them a humanly-thought-out human-readable error message rather than a
generic blob of unreadable gibberish.

------
bla2
C tooling is much better these days. If you run your code under valgrind or
address sanitizer with a good fuzzer, most of these concerns go away. True,
you might not need that for a memory-safe language, but you probably still
need to fuzz your parsing code if you want it to be any good. And enabling
address sanitizer requires adding one flag, so it's not all that much harder.

Hm, this arguments sounds similar to the "you need to write tests with good
coverage anyway" argument that fans of dynamically typed languages make when
they're told that static typing catches many errors at compile time :-)

------
warrenmiller
Who writes this crap?

~~~
codecondo
Mainstream media.

------
raverbashing
Problem is: C, while very powerful, ends up being a burden in today's complex
software.

It won by being less verbose and "more powerful" (for some uses) than Pascal
(amongst other things), however, the way software evolved it starts to pull
down.

There's a lot of unmanaged complexity in C (and in C++ it just ballooned);
things like Go, Python (and even Java) taught us that managing complexity is
important

It's very easy to shoot itself in the foot in C, C++ gives you a laser scope
on top.

Some software gets away with C (like the Linux Kernel) by being very careful
with it.

[https://twitter.com/id_aa_carmack/status/329210881898606593](https://twitter.com/id_aa_carmack/status/329210881898606593)

Can C be salvaged? Maybe D is the answer?

What I would do: built-in strings into the language (C's strings are pretty
much a syntax shortcut to a char array), safe strings, bounds checking, if you
want an array of bytes you get an array of bytes, not a string. Type aware
allocations (no more sizeof all around), maybe exceptions.

~~~
xamuel
When viewed as a performance language, it makes sense why C doesn't come with
built-in strings: there would be too much temptation for everyone to use
those, instead of the particular implementation of strings most performant for
the problem at hand (NULL-terminated or not? Stored with length or not?
Support for Unicode or not? Stored in a hash table? A radix tree? Or just
directly allocated with no attempt to remove duplicates?)

It's as silly as saying, "Different SQL string types are insecure, make
everything TEXT!"

~~~
raverbashing
> there would be too much temptation for everyone to use those, instead of the
> particular implementation of strings most performant for the problem at hand

That's why nobody uses the C string functions, right? Oh wait...

If you need something else just use it, but for the majority of cases you want
string functionality that is built-in and works (and hopefully is not a
ticking time bomb)

------
jjawssd
Blah blah blah. Another batch of anti-C/C++ propaganda by a technologically
illiterate ignoramus. If C/C++ are too difficult for you then stay out of the
way and use Ruby.

------
Roboprog
C! Made in AMERICA! (F--K YEAH!)

We can't be using any of those sissy languages made in Switzerland!

The real tragedy is that [Turbo] Pascal / Modula / Oberon / Eiffel never got
any traction. We could have been ahead of where we are now for low / medium
low level languages DECADES ago.

E.g. - Turbo Pascal:

* Checks array boundaries, but you can cobble up pointer arithmetic if you really need to squeeze something (it looks funny, as it _should_ , but it converts into the same assembly code as ptr += size ; _ptr)

_ references ("var" params) used safely as non-optional values in most cases,
using pointers for parameters that are truly optional.

* much stricter type checking and type range restriction allowed - most of which is only paid for at compile time, rather than run time.

* faster compiles, allowing quicker test cycles.

I suppose Ada fits in this group as well, but it was expensive in the late
80s.

Modern GC languages do well for long running application server programs, but
they don't make good "transient" utility programs. We still need lower level
languages for some types of programs.

Mobile could benefit from smaller memory footprints as well. I'm "gaming the
game", but here are some tests on a 32 bit quad core setup, sorting by memory
used for something that grinds through a number of connected objects as a
surrogate for bulk data twiddling:

[http://benchmarksgame.alioth.debian.org/u32q/performance.php...](http://benchmarksgame.alioth.debian.org/u32q/performance.php?test=binarytrees&sort=kb)

Alas, the Pascal version used 3 times the CPU seconds that the (fastest, but
2x more memory) GCC version did. However, a lot of work has been thrown into
tuning GCC. Also, there were 6 C/GCC solutions submitted for this problem, of
which 3 were not even correct. Of the other 2 C attempts, one was about the
same size and speed as the Pascal version, and the other was twice as big and
three times as slow.

~~~
rancur
I don't need array checking, sometimes I might want to use a negative indices
to access the last element

------
gcb0
inflammatory post. but it's techcrutch so what was i expecting?

this is the same as saying "armed concrete buildings fail more often then
buildings made of paper and bamboo" while completely ignoring that all the
world around them not even being possible without talented people building the
armed concrete structures around the ego of whoever wrote this.

------
trhway
Yes, blame the language.

~~~
rossng
Why not blame the language?

There are plenty of languages available that are objectively more safe than C.
Most of the security-critical memory-related bugs that are written in C (and
C++) simply could not happen in, say, Java or Haskell.

By contrast, even though it is technically _possible_ to write safe C, it is
mind-bogglingly hard. The problem is too difficult to be solved even by
automated static analysis, testing and fuzzing.

The reason those safe languages aren't used pretty much always boils down to
either a) legacy or b) performance. Rust solves the latter, but the former is
nigh intractable.

Simply expecting programmers to be better or more careful is not a viable
solution. The aviation industry knows this - problems can almost always be
attributed to a systemic cause, not the one-off mistake of an individual.
Problems are fixed by making those mistakes _impossible_ , not by reminding
people not to do that, crossing your fingers and hoping for the best.

This attitude is spreading to other industries - primarily healthcare[1]. In
the light of the ever-growing digital security threat, I think we should be
making the same kind of efforts in software engineering.

C has its niche, but I think it is important to recognise that it has its
tradeoffs. We should be trying to make things better.

[1]
[http://www.amednews.com/article/20100614/profession/30614994...](http://www.amednews.com/article/20100614/profession/306149945/4/)

~~~
seanwilson
Exactly, if a language makes a mistake virtually impossible to make, why would
you not want to take advantage of that? If there's even a small chance you can
make a mistake, it's inevitably going to happen given a large enough project.
For issues like security it's not scalable to just "be careful".

Also, as a programmer, I like to automate tedious problems away. I don't
understand why a programmer wouldn't want to automate away such a enormously
important issue.

~~~
xamuel
It's a real dilemma.

Sure, the safeguards make your code 5% less performant; who cares, right?

Now suppose your code has a dependency, which has a dependency, which has a
dependency, which has a dependency. And each level introduces a 5% performance
hit. Suddenly your product is 28% less performant. This is why you end up with
such nonsensical things as, e.g., the OWL API needing 2 gigabytes of RAM to
hold an ontology that should take 200 megabytes max.

~~~
seanwilson
Do you have links to any benchmarks about this? I can't imagine bounds
checking in practical programs has that much impact. For what impact it does
have you have to weigh that against the impact of security exploits. Most
languages with bounds checking have ways to eliminate bounds checks in certain
scenarios as well.

------
ExpiredLink
>> _…Which is why I’m so interested in Rust. It’s the one new programming
language that might, finally, at last, replace C and C++_

Oh, I see ...

------
fndrplayer13
All very true, I just think its still a little early to recommend Rust,
personally.

------
halayli
The ignorance in this article is way too high.

------
divs1210
I think the only way to end C is to port Linux to Rust/Nim/Julia/Scheme/etc.

------
astn
Ada.

------
prht
what a load of tosh

------
tritium
Pathetic human frailty has nothing to do with the validity of syntax. The
machines will do as we say, for the most part.

Don't be an ass, and don't whine about bullshit like extra curly braces and
semi-colons. Know your memory map. Get your shit together.

~~~
copsarebastards
So your solution is to come up with better humans rather than coming up with
better programming languages? Yeah, that will work.

