Ask HN: Why do so many developers dislike C when I find it inspiring?
12 silentpuck 41 7/30/2025, 5:46:55 PM
I write in C, and I constantly see posts or comments calling it dangerous, outdated, or unnecessarily complex.
But for me, C feels like freedom.
I can build exactly what I want — small tools, secure utilities, no magic, no garbage collection, no telemetry.
Yes, I have to think harder about memory and safety. But that’s the point. I want to be close to the machine. I want to know what my code does, byte by byte.
Still, I find myself wondering:
Why do so many people seem to dislike C? Is it just because it doesn’t protect you from yourself? Or am I missing something that I’ll regret later?
I’d really appreciate honest thoughts — especially from those who moved away from C.
Thanks.
One of my formative experiences was typing in a terminal emulator for CP/M from a 1984 Byte magazine and porting it to OS-9 on my TRS-80 Color Computer. It was quite the trauma to see 80% of the code was error handling with the error-prone pattern of checking errno. When I saw Java which had try-catch I was so delighted.
"Feels like freedom" is one of the most dangerous feelings out that that reminds you that feelings are not facts. Wasn't it Orwell that coined the slogan "Freedom is slavery?"
... and they still write programs blasted full of security holes and bugs that would be prevented in any other language. (Other that C++.)
Not that other languages are perfect or anything. But we've got decades of proof that C is full of sharp edges and that no, you (and this time I do mean you personally) aren't avoiding them. You just haven't noticed the bleeding yet... and the odds are good it's actually your users that will pay.
I consider greenfielding in C without the absolute best in static analysis backing you up to be professional malpractice. If you're not acting as a professional than that doesn't apply. But no professional should be doing that in 2025. And I consider "C backed with the absolute best static analysis" to still be something you need to be backed into, against your will, because of something very compelling for your project.
Also, the type system is bad, it lacks good closures, it can't abstract worth a toot, by 2025 it is legitimately a bad language despite all the attempted fixes over the decades. And I'm not a "use Haskell for everything" sort of guy... but C is just way, way too deep into the "costs" on the cost/benefits equation. It was a great language for the time, but we did not reach the epitome of programming perfection in the 1970s. I doubt we've reached it even now. Nobody should be reaching for C routinely now.
I advise spending some time learning Rust. I'm not saying that as a crazed Rust advocate... my actual experience with the language is limited to "I compiled Hello World once". But the borrow teacher will teach you a lot of important things about how to think about memory management. Then you will go back to C, and with a couple of hours you'll find yourself appalled. The resulting clarity you will see C with is completely accurate, and while you can get it from other places, Rust is a very efficient teacher of the problems I'm referencing here. In 2025 C is truly an appalling language.
I don’t claim to be immune to the sharp edges of C. I’ve already cut myself more than once. Maybe I’m bleeding now and don’t even know it yet.
But there’s something in me that still wants that control — even if it hurts. I’m not building for clients or large teams. I’m building for myself with intention.
Maybe I’ll shift later. Maybe I’ll come to hate C myself. But for now, every time I compile a C binary and see it run exactly as I built it — without layers, runtimes, or abstractions — I feel like I’m touching something real.
I’ll take a look at Rust. Not to escape C — but to understand memory from a different angle.
Thanks for your honesty.
There are many modern languages that give you control without giving you the grotesquely unsafe constructs that C gives you. You don't need to pervasively be able to access arrays out of bounds. You don't need to pervasively be able to do arbitrary pointer arithmetic. Even if you do need to fool with that stuff you can always do it in some unsafe block. We've built methods that give you the control you need without the control you don't need.
Alternatively, consider learning assembler. No joke. While theoretically all my complaints apply only moreso, assembler has the advantage that being "the language we speak to the CPU with" means that it will always still have some use until such time as we switch CPU architectures. At least in the assembler world you know you're juggling lit torches all the time.
Step by step, I want to get closer to what’s really going on.
Java is also a great language. I get why it clicked for you.
It forced me to understand memory, resource management, and what actually happens when you call a function or access a variable. No abstractions to hide behind — just the machine and you.
Even now, when performance matters, I often go back to C-level tools and techniques — mmap, manual memory control, system calls — because they give me the precision I need.
More importantly, learning C gave me fundamentals I don’t think you get as deeply with higher-level languages. It made it easier to pick up other languages, not just syntactically, but conceptually. I understand what they abstract away — and at what cost.
C isn’t perfect, and it’s not the right tool for everything. But if you want to understand computers, I still think it’s one of the best places to start.
And like it or not, there are still things that — for legacy, for portability, or for raw control — can only really be done in C.
If I needed to ship a product quickly and prove something to investors or customers, I would choose a higher-level language too.
For me, C programming is not about speed, it's about deep understanding, intention, and creating things that I truly understand and can control.
But I get it - at the end of the day, we all have bills to pay. Thanks for sharing your insight.
Software will continue to grow to the point where people move rapidly until they hit a limit. We laugh at future devs being weak, future devs laugh at our tech being unsafe.
I think you're right — being in the driver seat gives one kind of experience, but leading a team under pressure is a different challenge entirely.
I guess every generation of developers finds their own balance between freedom and safety.
Appreciate your perspective.
I often doubt myself when I see all the modern hate for C, but hearing from someone who used it when cycles mattered…
That means a lot.
I hope to earn that same kind of precision.
I stuck with it through the various iterations, right up to the point where Borland's management went insane, and they lost their chief architect to Microsoft. I tried C++ after that, but the amount of boilerplate and cruft compared to Delphi was just unbearable.
Things I personally hate about C include
Pascal is faster in compile and runtime. It's smaller, and has almost magical string these days.I guess in the end, we all gravitate toward the languages that feel like home.
I remember trying Python once — it didn’t click. Then C++ — and when I hit memory management, I didn’t turn away… I got curious.
So I looked deeper — into C. And somehow… I stayed.
Thanks for sharing that.
I still want to explore Rust at some point, but I think it’s important to hear real experiences like yours.
Sometimes the simplicity of C — for all its sharp edges — feels more honest.
My last big project was 100kloc C/C++ in a radiator valve though. Not many languages with a run-time would have fit in the 32kB code space for that project.
For me it's not about "modern safety" — it's about knowing that every byte is mine. But yeah, I get the tradeoff when you’ve got teams, timelines and a JVM.
I stick with C because (1) I'd have to figure out the tooling for 100% assembly development on AVR-8, and (2) C is portable to other platforms so if I want to migrate to an ARM or ESP-32 board it would be easy. (The upward migration path for AVR-8 is to go to a soft core on an FPGA but talk about frying pan to the fire)
But then I’d cool down… and come back to it. Some languages just never “clicked” for me, but somehow I keep coming back to C.
With namespaces you can have globals and few collisions. At the expense of more typing, of course.
You do know about the "register" storage class/keyword, I am sure. Sometimes it works.
Edit - the tooling for AVR assembler seems to be avr-gcc and make. Check out Nerd Ralph's "ArduinoShrink" library for an example of blended C and assembler:
https://github.com/nerdralph/ArduinoShrink/tree/master
I’d honestly love to read more about setups like that — maybe in my quiet hours. Feels like something worth studying, even if I keep walking the C path for now.
WHY does it matter to you to be that close to the machine? For many of us, we value different things. What you perceive as control, we perceive as fussiness.
For me, it’s not just about building tools — it’s about understanding what I’m building.
I like knowing where the bytes go. What the memory looks like. How the binary behaves. It slows me down, sure — but it teaches me things I didn’t even know I didn’t know.
I’m not building for scale or clients. I’m building to see.
That kind of closeness makes the machine feel less like a mystery, and more like a partner.
For me it's pretty hard to get in the flow with Python because I keep having to stop and read the documentation. I think this is just a personal thing but it's possible that Python may just be a significantly more complex language and that's driving some of it. I'm sure I'm not the only one like this.
There was a string heavy app I wrote years ago and I had multiple false starts in Python and then one day I just said "this needs to get done" and plowed through it in C nearly one shot in a couple hours. I've experienced this kind of thing multiple times. It's a little hard to really communicate how this feels.
EDIT: Yeah I think it really depends. I certainly do a lot of heavy numerical/ML stuff in Python just because that's where the libraries are (and IMO the libraries being written in python isn't a coincidence, it's a fantastic language for that.)
It's not just "string handling algorithms" though. I've written an entire web browser in straight C and it was mostly just walking through standards and coding. Maybe some of it is familiarity but I think part of the lack of familiarity comes from C just not having complex built-in data structures. There's no hashmap in C. There are no iterators in C etc. There's a tiny standard library to become familiar with and that's about it.
It sounds to me like part of that for you is about familiarity and another part might be about the specific problems you’re solving.
I’m usually working on solving problems at much higher levels of abstraction than string processing algorithms. For me, a big part of Python’s productivity is its ecosystem of useful abstractions (there’s an XKCD for that). And not having to worry about memory management or null pointers. How powerful exception handling is. Etc.
Python may in some ways be a more complex language, but I find it much simpler to reason about.
Honestly, a lot comes down to the person, the kind of problems they solve, their mindset… and sometimes, their scars.
I don’t even fully know why Python didn’t click with me. I understood it. I saw how fast it can be. But for some reason, I kept drifting back to C.
Maybe it’s just how my brain works. Maybe it’s where I found meaning. Hard to explain.
That’s why it’s been such a pleasure having this kind of conversation — thoughtful, respectful, and grounded. Thanks again. I’ve really enjoyed it.
Yeah the huge amount of libraries that are readily available and can be used right away without messing with a complex build system is a huge deal.
For me personally, C# is like the middle ground. A language I like much better than Python but also has a fairly rich ecosystem, and usually nuget makes including dependencies easy.
I’ve never spent serious time with it, but I’ve heard a lot of good things about the tooling and the ecosystem.
Maybe one day I’ll give it a try — especially if I ever need something with more abstractions but less ceremony than Python.
Thanks for sharing your take — it’s always helpful to hear how others find their flow.
New in the upcoming release[1] will be the ability to run C# files as if they were scripts[2], ie without an explicit build step. Should lower the barrier to just fooling around.
I also like how they've gone away from the "everything must be an object" style ala Java, and allow top-level statements so it reads more like C/C++. It's just sugar, but for smaller programs that really makes a difference IMHO.
[1]: https://news.ycombinator.com/item?id=44699174
[2]: https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...