Hacker News new | past | comments | ask | show | jobs | submit login

C is low-level enough to hang yourself and high-level enough to make it hard to tell when you've done so. It was a great language in the 1970's.



I think the hanging yourself in c comes from the syntactic complexity, not its high-levelness.

Several mistakes in c:

Using string interpolation preprocessor macros makes it so that you have to 1) learn a whole second language to read other people's code (most portable code requires using #defines) and 2) it's very difficult to trace through code where you don't know where some values are coming from.

Header/code segregation seems like a huge mistake. It's far more effective to have a single file with well-defined exports. Even the #include system is broken, because it's not explicit or obvious which directories one must go to to find header files (they might not be local to your project)

Sigil order. The fact that there is a guide saying you should "spiral out" to understand how to read a type should be evidence enough that this is a huge mistake.

I get it that there are professional c coders that will say that's part of knowing the language. I'm not a professional c coders, I program in another language and very rarely need to dip into something lower, say for performance or mutability. Thus the c code that I should write is dangerous, I need safety, and simplicity. Luckily, I found another language that hits those spots.


syntactic complexity is just the surface, just wait until you compile and run the program and watch buffer overflow, strict aliasing, signed overflows, undefined behavior, and other optimizations and "you have direct access to the memory"-cargoculting silently expose all kinds of vulnerabilities in your program.


When you hang yourself with C, at least you're hanging yourself with something real. It's more embarrassing to be done in by a misunderstood abstraction in a high-level language than a concrete memory overwrite in C.


‪If you can’t hang yourself with it, is it even real? Do you hang someone with a rope, or with a knot? Abstractions are knots, not ropes.‬


You can hang yourself in C by having code that would dereference a NULL pointer that never actually would be executed, yet the compiler “optimises” your code based on it. Is that “real”?


And is now obsolete, for the most part. Unless you want to do something on hardware that only has C support, there are generally better options. The language has not evolved. There are now several good alternatives in this space.

Edit: Rather than responding to all the comments individually: There's obviously a lot of code already written in C. That doesn't mean it makes sense to write new code in C. Sometimes C is your only option, which I already said in my original comment.

None of that means there is any reason to start a new project in C if it's going to run on Windows or Linux, and it's certainly not the case that you have to write your program in C if you want to call it from another language. Sorry if this disappoints anyone, but it's true. For the traditional uses of C, such as writing a text editor or a library for numerical computing that you're going to call from another language, there's no longer a sensible argument for using C.


Except the entire world basically runs on top of C, and any library that wants to be usable from different languages is still written in it. Which is a pretty weird definition of obsolete. Don't use it if you don't want to for whatever reason, but spreading FUD to protect your bubble doesn't help anyone. C is the most successful programming language ever designed, and a fine tool in the right hands. It's not perfect, nothing is, anyone telling you otherwise is lying.


> any library that wants to be usable from different languages is still written in it.

This part isn't quite true. All that's needed is to be able to define an exported function with a specific name and calling convention. Libraries can be written in any language that supports these features.


I used to do some of that in Borland's Object Pascal, which sort of works but isn't much fun.

Even C++ is a pain in the behind, because everything that doesn't translate needs to be encapsulated.

As a result, it's very rare to find code written in different languages with exported C APIs from my experience.


And the language needs to hide its runtime support so it appears to be as minimal as C


And anything that C can do C++ can also do but better and easier and safer. So yeah... Obsolete.


That's just not true, because C++ won't even allow many of the techniques that make C the awesome language it is. It's different, and that's about as far as it goes.

Add name mangling, ABI issues and crazy compile times to that.

It was potentially safer until they added Exceptions, which tipped the scales so far the other way I can't believe we're still having this discussion.


There's Itanium ABI, you can use C type interfaces when needed and suppress name mangling. How do exceptions make it unsafe? They're part of idiomatic C++ and solve a problem without anything unsafe about them. And what are the many of the "awesome C techniques" that you can't do in C++?


Itani-who?

But you won't when writing C++ unless you absolutely have to, because it's a major pita to encapsulate everything.

Entire books [0] have been written about exception safety in C++. Getting it right in combination with RAII, (copy)-constructors and assignment operators is very tricky. Which touches the main issue with C++ from my experience, mixing foot guns with higher level convenience.

Embedded linked lists [1] is a good example.

Seriously, live and let live. I'm fine with you enjoying and preferring C++, go for it. But consider taking a good look in the mirror and asking yourself why you feel the need to spread FUD about C to feel good about your choice.

[0] http://www.gotw.ca/publications/xc++.htm [1] https://github.com/codr7/libceque/blob/master/source/libcequ...


I can honestly say that C++ exceptions have never, in decades, cost me a single hour's lost sleep. If you have any trouble with them, I promise that you are Doing It Wrong. You can tell you are Doing It Wrong if it is not super-easy and super-clean.

The key is to make sure all your cleanup code is in destructors where it will be exercised frequently as part of the normal operation of your program. In the event an exception is thrown, a bunch of destructors run, as usual, and your program ends up in a known clean state, with no extra effort.


Just do not expect Linux (the kernel) to be rewritten in some other language any time soon.


We will have to move to microkernels at some point. Maybe this is the correct point.


Hypervisors, most likely.

Linux (like the BSDs) being C is an organizational phenomenon. There is no plausible technical reason for it not to be, or include parts in, C++. History is path-dependent; how we got here matters more than what is around today.

There is really no excuse for systemd being C. It is really a drag on its development.


UNIX and C are symbiotic, to get rid of C we need to get rid of both.

On the OSes that aren't just plain UNIX clones, C has a much less relevant role, and in some of them it is even being phased out, even if it might take a couple of decades yet.


I vaguely recall that Windows originally was leaning towards Pascal.


At the time everyone was sure that Pascal was The Future of both OS and app development.

What happened instead was that everybody had their own Pascal dialect with the extensions it needed to be actually useful. Meanwhile, C had them all, already, and was about the same everywhere. Soon after, C++ came along, and there was again only one (although Microsoft delivered workable template support very late).

Lesson in Network Effect there. Also, shooting for usefulness out the gate.

Meanwhile, the Pascal crowd went off with Modula-2, Modula-3, Oberon, Apollo Pascal, UCSD Pascal, Object Pascal, Delphi, and countless others, none compelling. Apparently Delphi (still) has economic importance. The rest, not so much.


It used the Pascal calling convention, however Lisa and Mac OS were implemented in a mix of Pascal and Assembly.

Pascal UCSD also used a mix of interpreter and later AOT compiler.

Most mainframes don't use C as their original implementation language, and the oldest still being sold (Unisys ClearPath MCP) was designed about 10 years before C was born, in an Algol derived language, that uses instrics instead of Assembly.

If one broadens their horizons beyond UNIX, and looks into the history of computing there are plenty of interesting languages and OS architectures to dive into.

The Internet is full of digitalized version of papers and computer manuals from those days.


The language hasn't evolved for the same reason a transistor hasn't evolved: because it didn't need to. Adding for example string manipulation, or graphics, etc. would make it a fantastic language, but it would lose being that minimalist tool which makes it often the best choice when writing low level stuff. To me, Crystal, Nim, Rust, Go etc. already fulfill that need. About the electronics comparison, I can build a lot of complex stuff more fast and more easily using opamps or logic gates compared to discrete transistors, but if I need to do a simple basic task such as invert a logic signal or amplify an analog one I'm using a single transistor any day because it doesn't just spare all that wasted silicon in chips but also in many cases it will be more fast, more cheap and more quiet noise-wise.


Wrong. Transistors have evolved in dozens of directions. The old transistors are still used, but decreasingly so. It is likely an op amp does better what your transistor and a bunch of other stuff did, and equally as cheaply. The op amp might have bipolar transistors in, but just as likely not.

C has not evolved because C++ has, and because the computers got a million times faster, so even Python is usually good enough. If you need something that does what C does, but better, C++ is right there waiting. Change your makefile, or rename some files, and suddenly you have a C++ program, that is then easy to improve as much as you like.


>C has not evolved

Well, it has, in a way: see the latest C standard and compare it with the Kerninghan&Ritchie edition.


C has barely changed since 1989. It already had void and function prototypes copied from C++, back then. Only atomics and restrict make any real difference.


>The language hasn't evolved for the same reason a transistor hasn't evolved: because it didn't need to.

That's what you think. Transistors have evolved a lot, as have programming languages.


I meant functionally, ie what a single part (bjt, jfet, mosfet etc) can do. of course there are better materials and ways to produce more advanced parts.


There is no good alternative for doing some low level thing where you must have fine control over IO or execution sequence.

Rust is the best candidate, but it operates on a completely different level. (That said, I don't think one ever need that much control on a PC or a server. Not even on kernel programing.)


C++ is entirely capable of every single thing you can imagine doing with C.


Turbo Pascal and Modula-2 were good alternatives back in the 8 and 16 bit days.

There are other modern alternatives nowadays as well, including for MCUs.


C is basically your only option for embedded systems.


False, of course.

It's the only language your chip vendor will give you, but there is very little reason ever to use their compiler, anymore. And they have no say in what you use to generate your machine code.


Depends on the project and chip vendor.

Anyone that is open mindend can get Pascal, Basic, Java, Oberon, C++ and Ada compilers, although I admit that the Ada option is only available for deep pockets.


I'm not sure languages like Pascal and Basic are better options...


In what concerns lack of memory corruption and UB features, much better.


It's still a great language and still the industry standard for embedded. If you can't figure out C, an incredibly small and simple language, you probably shouldn't be programming.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: