Live data from Hacker News

Why I Always End Up Going Back to C

deplet.ing

21–30 of 76 posts

Re: Why I Always End Up Going Back to C

#21
post #18
post #7

> The language shows you the machine, a machine which is not forgiving to mistakes. Assembly does that, C not really, it is a myth that it does.

True, it doesn't give you the bare machine. What it gives you is the thinnest of machine abstraction with the possibility of linking to your own assembly if you have the demand for it.

Yet another myth, plenty of languages since JOVIAL in 1958 offer similar capabilities.

Re: Why I Always End Up Going Back to C

#22
Good Article. The author has touched upon all the points that make C still attractive today.

A few more points;

C allows you program everything from dinky little MCUs all the way to honking big servers and everything in-between. It also allows you to span all levels of programming from bare-metal, system-level (OS/System utilities etc.) to any type of applications.

There has also been a lot of work done and available on Formal Verification of C programs Eg. Frama-C, CBMC etc.

Finally, today all LLM agents are well trained on the massive publicly available C codebases making their output far more reliable.

PS: See also Fluent C: Principles, Practices, and Patterns by Christopher Preschern for further study.

Re: Why I Always End Up Going Back to C

#23
post #21
post #18

Earlier quoted context omitted.

True, it doesn't give you the bare machine. What it gives you is the thinnest of machine abstraction with the possibility of linking to your own assembly if you have the demand for it.

Yet another myth, plenty of languages since JOVIAL in 1958 offer similar capabilities.

Ok, if you insist on ultra precise description - "C is is the lowest level language among widely used".

Re: Why I Always End Up Going Back to C

#24
post #21
post #18

Earlier quoted context omitted.

True, it doesn't give you the bare machine. What it gives you is the thinnest of machine abstraction with the possibility of linking to your own assembly if you have the demand for it.

Yet another myth, plenty of languages since JOVIAL in 1958 offer similar capabilities.

I am curious, what was it I said that you consider to be a myth? If I have some misunderstanding I would like to know. I looked at JOVIAL on wikipedia quickly but I can't see exactly how it would be thinner than C or if it's compiler would output something vastly different to a C compiler. Or did you mean it's as thin as C but it came out earlier?

Re: Why I Always End Up Going Back to C

#25
post #16

Earlier quoted context omitted.

If software development taught me anything it is that everything that can go wrong will go wrong, the impossible will happen. As a result I prefer having less things that can go wrong in the first place. Since I acknowledge my own fallibility and remote possibilities of bad things happening I have come to prefer reliability above everything else. I don't want a bucket that leaks from a thousand holes. I want the leak…

This is, perhaps surprisingly, what I consider the strength of C. It doesn't hide the issues behind some language abstraction, you are in full control of what the machine does. The bug is right there in front of you if you are able to spot it (given it's not hiding away in some 3rd party library of course) which of course takes many years of practice but once you have your own best practices nailed down this doesn't…

How is one in full control of SIMD and CPU/OS scheduling in NUMA architecures in C?

Re: Why I Always End Up Going Back to C

#26
post #2

C sounds nice if your task is simple enough, or at least if you can decompose this to a series of loosely-connected simple-enough tasks. But sometimes, there is an inherent complexity in what you are trying to implement, then C becomes way, way complex than C++. You build stuff, and there is so many manual steps, and none of them must be missing, or things will subtly break. A good example is "gstreamer", the multime…

> It needs to use basic data structures, so it uses GLib. It also need to support runtime-defined connection graph, so it is built on top of GObject. That's running into the age old trap of trying to shoehorn an OOP system into C, just don't do that ;) E.g. don't design your systems around the OOP paradigm in the first place.

You know what gstreamer does, right? It's a dynamic multimedia framework - you give it pipeline defined by string, like:

ximagesrc display_name=:1 ! video/x-raw,framerate=20/1 ! videoscale ! videoconvert ! x264enc tune=zerolatency bitrate=500 speed-preset=superfast ! rtph264pay ! udpsink host=127.0.0.1 port=5000

and it automatically loads .so files, creates all those components and connects them to each other. Super handy for all sorts of fun audio/video processing.

So all that C ceremony is required because user _should_ be able to say "ximagesrc display_name=:1", and possibly dynamically change this attribute to something else via script command (because a lot of time gstreamer is embedded in other apps).

So if you know how to achieve the same without trying to "shoehorn an OOP system into C", do let me know. But I bet whatever solution you came up with would be very close to what GStreamer ended up doing, if not even more complex.

(Unless what you are trying to say is: "If problem's most-efficient representation is OOP-like, don't use it with C because C is for simpler problems only. Use complex languages for complex tasks." If that's the case, I fully agree)

Re: Why I Always End Up Going Back to C

#27
post #20

Earlier quoted context omitted.

> If at least C solutions took advantage of abstract data types as advocated by modular design approaches People have been writing C code with ADTs and "Modules" from the very beginning. Two excellent examples which come to mind are; Andrew Tanenbaum's Minix book Operating Systems Design and Implementation and David Hanson's C Interfaces and Implementations: Techniques for Creating Reusable Software . And of course t…

Unfortunely I have seen plenty of counter examples since 1991. Starting with RatC from "Book on C", 1988 edition, over to Turbo C 2.0 in 1991, all the way to modern times. That is just not how most C codebases look like.

Nope, you are just generalizing your opinion which is not quite true. My (and my colleagues) experience studying/programming C/C++ from the beginning-90's has been pretty good.

When the PC explosion happened, a lot of programmers without any CS background started with C programming and hence of course there is a lot of code (usually not long lasting) which do not adhere to software engineering principles. But quite a lot more C code was written in a pretty good style which was what one picked up at work if not already exposed to them during studies.

I still remember the books from late-80's/early-90's on the PC side, by authors like Al Stevens (utils/guis/apps using Turbo C) who wrote for Dr. Dobb's Journal. On the Unix side, of course you had Richard Stevens, P.J.Plauger, Thomas Plum etc. They all taught good C programming principles which are still relevant and practiced today.

Re: Why I Always End Up Going Back to C

#28
post #8

Earlier quoted context omitted.

> It needs to use basic data structures, so it uses GLib. It also need to support runtime-defined connection graph, so it is built on top of GObject. That's running into the age old trap of trying to shoehorn an OOP system into C, just don't do that ;) E.g. don't design your systems around the OOP paradigm in the first place.

Unfortunately your insightful comment is 30 years too late. You'll have to find a time-machine and go back to the 1990s and tell GNU/GTK/Gnome/etc that they are doing it wrong.

Good luck making any sort of UI without OOP-like methods. The moment you have grouped state (say "button_enabled", "button_shown", and "button_checked") and corresponding methods, you get something OOP-like.

The only way to work around is immediate mode UI, but this requires fairly powerful CPU, so it's only feasible on the modern machines. Certainly not something that people would want about 30 years ago, they still cared about performance back then.

Re: Why I Always End Up Going Back to C

#29
post #5
post #2

C sounds nice if your task is simple enough, or at least if you can decompose this to a series of loosely-connected simple-enough tasks. But sometimes, there is an inherent complexity in what you are trying to implement, then C becomes way, way complex than C++. You build stuff, and there is so many manual steps, and none of them must be missing, or things will subtly break. A good example is "gstreamer", the multime…

> You build stuff, and there is so many manual steps "The real goal isn’t to write C once for a one-off project. It’s to write it for decades. To build up a personal ecosystem of practices, libraries, conventions, and tooling that compound over time."

You mean, you are not worried about high complexity of codebase because you work with it every day for decades, so you know all this complexity by heart?

This basically requires one to be working solo, neither receiving not sharing the source code with others, treating third-party libraries as blackboxes.

I guess this can work for some people, but I don't think it would work for everyone.

Re: Why I Always End Up Going Back to C

#30
post #25
post #16

Earlier quoted context omitted.

This is, perhaps surprisingly, what I consider the strength of C. It doesn't hide the issues behind some language abstraction, you are in full control of what the machine does. The bug is right there in front of you if you are able to spot it (given it's not hiding away in some 3rd party library of course) which of course takes many years of practice but once you have your own best practices nailed down this doesn't…

How is one in full control of SIMD and CPU/OS scheduling in NUMA architecures in C?

Linux has libnuma (https://man7.org/linux/man-pages/man3/numa.3.html) while Windows has its own NUMA api (https://learn.microsoft.com/en-us/windows/win32/procthread/n...)

For CPU/OS scheduling, use pthreads/OpenMP apis to set processor affinity for threads.

For SIMD, use compiler intrinsics.

Post reply on HN