[HN Gopher] I write games in C (yes, C) (2016)
___________________________________________________________________
I write games in C (yes, C) (2016)
Author : valyala
Score : 249 points
Date : 2026-02-07 17:45 UTC (1 days ago)
(HTM) web link (jonathanwhiting.com)
(TXT) w3m dump (jonathanwhiting.com)
| Keyframe wrote:
| In my core I'm the same. C is my language and served me well for
| decades. There's nothing inherently major wrong with it until you
| reach one of the two (or both). Working in a group of people on a
| C codebase tends to introduce pain on multiple levels unlike some
| other languages (yes, including C++). The other is that anything
| takes a long-ass time to do compared to modern alternatives,
| which might also be an issue if you're developing a game;
| Especially if you're developing a game. Having said that, I can't
| disagree since as I said, I'm also inclined towards it's siren
| call of simplicity.
| uecker wrote:
| Why do you think working with a group of people on a C codebase
| introduces pain unlike other languages? Working with a group of
| people always causes pain, but I found the pain much less
| severe for C than for C++.
| dragonelite wrote:
| In my mind using a simpler language should be less painful
| given there is less to argue about given syntax and versions
| etc. Take c# for example you have multiple ways to do the
| same sort of things.
| Keyframe wrote:
| Your question also hides an answer. You don't often get to
| chose a group of people you work with, and unlike projects
| that self-attract and self-distill ideal profile (like linux
| mentioned in sister comment), you're left with people usually
| not used to ye olde C idioms. With C++ it's a bit easier
| since it is more widespread and supports some of the idioms
| people get used through schools and other projects. Of
| course, projects (should) always dictate a certain discipline
| by different mechanisms, but if certain way of thinking isn't
| ingrained then it introduces just that much more pain to the
| communication layer between people.
| uecker wrote:
| I would argue that is is much harder to find a group of C++
| programmers who write a coherent style of C++. In C there
| is not nearly as much to decide. Note also that I am
| speaking from experience with both.
| direwolf20 wrote:
| C relies on the programmer to understand the lifetime of
| every object in the program, which is global structure. When
| the programmer is multiple people, it's easy to get out of
| sync. unique_ptr from C++ solves 90% of this.
| smallstepforman wrote:
| Ever use a leak detector? Even my graphics engines (with
| shared resources) uses a leak detector in debug mode. The
| monent you forget to release a resource, assertion at
| program termination.
|
| Leaks are trapped with tooling, and all you need is one dev
| in the team to be diligant to run valgrind or visual leak
| detector or similar.
| uecker wrote:
| We run valgrind and asan as part of the CI, so it is
| checked before every merge and no developer has to be
| particularly diligent. But it is also not something that
| triggers a lot.
| direwolf20 wrote:
| Do you think the best way to avoid bugs is to thoroughly
| test your code, or does understanding the code while you
| write it also help?
| saidinesh5 wrote:
| It depends on what you're building with the language too.
|
| For eg. In very embedded contexts where we were not using any
| big data structures like struct of strings, not doing any
| memory allocations etc... C might be easier to reason about
| than C++. (No hidden code paths). Just allocate something on
| the stack, pass the pointer to a function to do the
| computation, done.
|
| In any desktop apis (gui, web servers etc..), where you deal
| with collections of objects, need to spin up thread pools and
| rely on results from the future etc... The standard library
| data structures (vectors, maps etc...) alone makes C++ code a
| lot more easy to read and review than C. When raw pointers
| are forbidden, Ownership of memory becomes very clear.
| Granted my opinion of desktop development comes mostly from
| very few libraries (Qt vs. Gtk, gstreamer's C API vs. C++
| wrapper, http libraries etc...), but there are some problem
| domains for which C is just insufficient.
| NuclearPM wrote:
| > Having said that, I can't disagree since as I said, I'm also
| inclined towards
|
| Say more with less.
| heliumtera wrote:
| >Working in a group of people on a C codebase tends to
| introduce pain on multiple levels unlike some other languages
|
| linux attracted 2,134 developers in 2025
|
| that kinda weakens your argument a little bit
| jonahx wrote:
| Maybe (and I like C, for the record), but it doesn't follow
| necessarily. It's possible most of those devs were attracted
| by "working on linux," and are putting up with the pain of
| collaborative C. I know there's a movement pushing for more
| Rust.
| tialaramex wrote:
| I think the popularity of Rust for Linux is also in part a
| reflection of internal discontent with poorly documented
| and sometimes straight up poorly understood kernel internal
| APIs.
|
| When a developer asks _Can_ I Fizzle this Doodad? C is
| comfortable with the answer being "It'll definitely
| compile but whether it would work is complicated - ask the
| expert on Fizzling and the Doodad expert, and hope they
| give the same answer" but Rust wants the answer to be "Yes"
| or "No" or at the very least, "Here is some actual text
| explaining when that's fine"
|
| Sometimes it really is hard work to figure this out but for
| a project as big as Linux even in those cases it's often
| worth doing that hard work, because you unlock something
| valuable for every non-expert contributor and Linux has a
| _lot_ of those.
| Keyframe wrote:
| It proves the argument as an outlier. I explained in another
| comment. You often don't have the luxury of selecting the
| group of people you work with and more often than not,
| especially these days, people aren't used to (C) way of
| thinking which just introduces more noise to the
| communication between people.
| smallstepforman wrote:
| If Linus started his OS project in 2026, he might have chosen
| Zig instead of C.
| vascocosta wrote:
| I totally resonate with the author of the post. My main
| requirement to enjoy a language deeply is often simplicity, so I
| love languages like, C, Golang, Odin and Zig.
|
| That said, I also acknowledge that often times I need to solve
| problems that can benefit from a language that embraces what I
| call necessary complexity, but do it in elegant ways. Whenever I
| need to prioritise code correctness, especially memory and
| concurrency safety, using a mostly functional pattern instead of
| OOP, but without going as extreme as say Haskell, I
| unquestionably choose Rust, my favourite complex language. I
| often work with network code that is highly concurrent, must be
| as correct as possible and benefits from good performance, so
| then again, Rust feels natural here.
|
| On the other hand, I love coding simple indie games and for that
| particular case, I like a simple and performant language using an
| imperative, non-OOP style. In my opinion C, and in particular
| Odin more recently are quite a good fit. If Jonathan happens to
| be reading this comment, since he mentioned Golang, I would
| suggest him Odin as perhaps the best of both worlds between C and
| Golang. It has all the simplicity of Golang, but without a
| garbage collector, plus it is quite easy to code a game using
| Raylib.
| pjmlp wrote:
| The language is called Go, golang is the website domain.
| ternaryoperator wrote:
| The use of "golang" for posts and comments is desirable IMHO
| because it greatly facilitates search, especially on sites
| such as HN that cover many languages.
| 9rx wrote:
| Searching "site:news.ycombinator.com go" on Google didn't
| yield any results that weren't about the Go programming
| language even after going several pages deep. What kind of
| search problems are you having, exactly?
|
| And why is it unique to Go? I am sure there are comments on
| HN about metal oxidization, making sharp changes in
| direction, Norse gods, and letters of the alphabet.
| ternaryoperator wrote:
| But if you go to the search box at the bottom of the HN
| page and type in 'go' the first hit is "Julian Assange
| has reached a plea deal with the U.S., allowing him to go
| free," In the top 10 results, only _two_ are about Go,
| the language.
|
| Whereas the first 50 golang hits are all about the
| language.
|
| You might have your preferred approach, but there are
| good reasons for using golang.
| 9rx wrote:
| _> but there are good reasons for using golang._
|
| Such as? If you type in 'C' into HN's search box, the
| first result is about the F.C.C., followed by C.E.O.,
| then USB-C. Even once we finally see one about a
| programming language, it is about C#.
|
| If the earlier list was instead 'Clangclang, Golang,
| Odinlang and Ziglang' then I could maybe understand where
| you are coming from, but that is not what we saw. Clearly
| there was no effort put into aiding searchers
| universally.
|
| Are you trying to suggest that Go is the only language
| worth reading about? Let me try to restate the earlier
| question in your tongue: Why is it unique to 'golang'?
| pjmlp wrote:
| I suggest admins to rename the post title as " I write
| games in Clang (yes Clang)", given how hard it is to find C
| content.
|
| It might end up finding stuff about a compiler though.
| vascocosta wrote:
| I know, but I often use Golang for two reasons: 1. avoids
| confusion, no matter how unlikely it is in a context like HN,
| and 2. search engine "findability".
| 9rx wrote:
| _> 1. avoids confusion, no matter how unlikely it is in a
| context like HN_
|
| Who would be confused by "Go", but not "Rust" and "Zig",
| which are also common English words not usually associated
| with programming languages?
|
| _> 2. search engine "findability"._
|
| What kind of search engine are you using in 2026 that isn't
| capable of understanding context?
|
| And where one is still using some weird antique thing like
| a steampunk character, "C" is going to be the least
| findable, yet it didn't receive the same treatment. Why is
| that?
| Melonai wrote:
| At least with regards your second point, Google,
| DuckDuckGo, all other search engines. I always have to
| add "golang" because otherwise it just fucks up. I have
| to say that googling for "C", is a lot more dire, and
| because the LLVM people called their frontend "clang" I
| can't even use that, otherwise only clang stuff pops up.
| And even then, once I did manage to convince the search
| engine that I'm looking for the programming language, it
| still decides to just give me results for C++. It sucks.
| win311fwg wrote:
| _> because the LLVM people called their frontend "clang"
| I can't even use that_
|
| Said frontend is for the C programming language. Isn't
| that perfectly appropriate? I did a web search for
| "golang" and the first result was a download page for a
| Go compiler, so there is precedent.
| direwolf20 wrote:
| What's the first result for "clang"? How about in private
| browsing?
| win311fwg wrote:
| A page about a C compiler. Not unlike the "golang"
| result, except without the same level of polish. The
| download link is similarly present, although due to the
| design choices doesn't stand out as the primary focus
| like it does in the "golang" case. I would consider the
| basic intent to be the same for both.
|
| Which is the best one could hope for given that the
| search engine doesn't control the content. If I am
| searching for "golang", a Go compiler is the most likely
| thing I would want to find. Presumably someone who
| already has a Go compiler installed will have more
| specific queries. Likewise, if I am searching for
| "clang", a C compiler is also the most likely thing I
| would want to find. For all intents and purposes that is
| the entry point into using a language.
|
| All in all the search engine did a great job and gave
| exactly what I would have expected.
| 9rx wrote:
| _> I can 't even use that, otherwise only clang stuff
| pops up._
|
| The searchable form is 'clanglang'. golang is the
| language compiled by the go compiler, like erlanglang is
| compiled by the erlang compiler, and clanglang is
| compiled by the clang compiler.
| Zambyte wrote:
| > I would suggest him Odin as perhaps the best of both worlds
| between C and Golang.
|
| It's interesting to me that you say this, because it's the
| exact way that I describe Zig to people. Especially with the
| new std.Io async / concurrency changes. Do you feel Odin fits
| the space between Go and C better than Zig? Or just
| differently, and they both share the same space?
| webdevver wrote:
| its funny how writing games in C is now seen as some kind of
| 'hardcore mode', despite the fact that a huge number of excellent
| titles up to and including the 2000s were written that way.
|
| the core of games tend to be a 'world sim' of sorts, with a
| special case for when a select entity within the world sim gets
| its inputs from the user.
|
| where C becomes a chore is the UI, probably has to do with how
| theres many more degrees of freedom (both in terms of
| possibilities and what humans consider appealing) in the visual
| plane than there is in the game input 'plane', which might be as
| little as 6 independent inputs plus time.
| namuol wrote:
| > UI in C
|
| Try Clay!
|
| https://www.nicbarker.com/clay
| pansa2 wrote:
| There's also CimGUI. I know the underlying C++ library is
| well-regarded - I'm curious to hear people's experiences
| using the C wrapper.
|
| https://github.com/cimgui/cimgui
| pengaru wrote:
| For quite some time even games technically written in C++ were
| more appropriately described as C compiled by a C++ toolchain
| with a minimum of actual C++ syntax - more like C with classes.
| glimshe wrote:
| Rollercoaster Tycoon was written in assembly! C was easy mode
| back in the day...
| NewsaHackO wrote:
| >Death of flash
|
| >The library support for games[in Go] is quite poor, and though
| you can wrap C libs without much trouble, doing so adds a lot of
| busy work.
|
| I can't see when this was written, but it has to be around 2015.
| So, about 10 years ago. I wonder what his opinion is today.
| QuantumNomad_ wrote:
| The first capture of the page on Internet Archive Wayback
| Machine is from January 9th, 2016. So it's at least that old.
|
| Also here is a snapshot of the main page of his website from
| that time, which has screenshots of his games and thereby
| provides context into what kind of games he had made and
| published when the blog post was written.
|
| https://web.archive.org/web/20160110012902/http://jonathanwh...
|
| This one looks like it's 3d and has a pretty unique style:
|
| https://web.archive.org/web/20160112060328/http://jonathanwh...
| edu wrote:
| I think it would be apropiate if @dang added a (2016) to the
| title
| leecommamichael wrote:
| Come try Odin!
| andai wrote:
| +1 for Odin
|
| Did a bit of game dev in Odin last year and it was a wonderful
| experience. It's very much game dev oriented and comes
| batteries included with many useful libraries. And the built in
| vector stuff is very helpful there too.
| doublerabbit wrote:
| I've been doing theory and really want to myself.
|
| Time escapes me before I get a chance to type Hello World.
| Working in front of a screen eight hours a day leaves me
| exhausted that the least things I want to do is code more on my
| day off.
|
| Although wanting to dive in to WASM has been a priority and
| checking Odin for wasm their 3D model example is super cool.
|
| May just have to take a poke. TCL for web frontend; Erlang for
| DB and potentially Odin for wasm? This could be a cool mix.
| andreldm wrote:
| I was also really surprised with Haxe, I share the author's
| concerns about its future, other than it's quite fun to work
| with.
| dismalaf wrote:
| Haxe is a great language but it feels like the ecosystem has
| been stagnant for 10 years. No Vulkan bindings, no SDL3, still
| trying to be a web language that happens to compile to native
| code instead of getting with the times and going fully native +
| maybe wasm. Part of me wants to write my own bindings to SDL3
| in Haxe but it's far easier to just use Odin these days.
| stephc_int13 wrote:
| "nobody does this"
|
| Well, this should be reformulated a bit. Using C is not the norm,
| but it once was and many people are still using C to write games,
| myself included.
| IshKebab wrote:
| When people say "nobody .." or "everybody .." they often -
| maybe even usually - do not literally mean 100.000000% of
| people. You are an outlier. He is still correct to say "nobody
| does this".
| graemep wrote:
| > when it comes to compilation I can't think of anything faster.
|
| What languages compile fastest?
| arcologies1985 wrote:
| Rust can be up there with C depending on the project.
| NewsaHackO wrote:
| is that a joke?
| enricotr wrote:
| Any language can be, depending on the project. Rust compile
| is slower than C, on more than average. That's it.
| gfody wrote:
| nothings faster than turbo pascal
| levodelellis wrote:
| IIRC go wasn't that fast but can feel like it in vscode. IIRC
| vscode compiles go using the lsp which is faster than launching
| a process because for some reason, vscode stalls for a second
| or more before launching a process.
|
| I can't remember how fast D was but iirc it was fairly fast.
| Actual fastest is my compiler which I don't work on anymore and
| isn't ready for production. It's the only compiler I know of
| that hit millions of lines <1s in a non trivial language
| https://bolinlang.com/
| tmtvl wrote:
| Not every compiled language has a de facto standard compiler,
| but with SBCL Common Lisp compiles pretty quickly. The Pascals
| (and Delphi) also tend to have rather fast compile times. I
| believe Jai is supposed to compile quickly but I'm not in the
| beta so I don't know. C can be quite good if you know what
| you're doing and use a decent compiler.
| graemep wrote:
| I should really have specified fast compiling
| implementations.
|
| It does make me wonder why Pascal never became more popular.
| Fast compiling is a big advantage.
| elcritch wrote:
| Nim compiles fast.
| drnick1 wrote:
| Literally thousands of games have been written in C, and all
| graphics APIs (OpenGL, Vulkan, DX) are C APIs, so it isn't weird
| at all. All major game engines are also written in C/C++.
| jiggawatts wrote:
| DirectX is C++ (technically a set of COM interfaces) and most
| game engines are also C++.
|
| Unlike, say, Linux programming where C is the standard, almost
| all games have been written exclusively in C++ for a long time
| now, probably three decades.
| cedilla wrote:
| There are a few exceptions though, like most mobile games,
| visual novels (many of which use Python of all languages, due
| to an excellent framework called ren'py), and of course games
| written using Unity or XNA, which use .NET languages.
|
| Also, three decades is going a bit too far back, I think. In
| the mid nineties, C was still king, with assembly still
| hanging on. C++ was just one of several promising candidates,
| with some brave souls even trying Java.
| pjmlp wrote:
| In J2ME feature phones Java was all there was, and even
| today many indies do use it on casual titles on Android.
|
| Which is why after so much resistance not wanting to use
| the NDK for Vulkan, and keeping using OpenGL ES from those
| devs, Google is bringing WebGPU to Java and Kotlin devs on
| Android.
|
| Announced at last Vulkanised, there is already an alpha
| version available, and they should talk more about it on
| upcoming Vulkanised.
| jiggawatts wrote:
| > Also, three decades is going a bit too far back
|
| My memory was wrong: I was thinking of the Quake 1 engine,
| but I just looked it up and it's C with some assembly code,
| no C++. The reason I remember it being C++ was because
| Visual C++ was the compiler tooling required on Windows.
| direwolf20 wrote:
| COM was designed to be compatible with C. Linux games are
| also often written in C++. The ones written in C are just
| old.
| jiggawatts wrote:
| Sure, but in practice COM is almost never used from C
| programs unless there is some integration into a very
| legacy codebase. Games are newly developed, they're not
| enterprise database platforms.
| direwolf20 wrote:
| OpenGL is commonly used from C++ too, or Java, but you
| labeled it as C.
| lelanthran wrote:
| > DirectX is C++ (technically a set of COM interfaces) and
| most game engines are also C++.
|
| So? Their interface is via C, just like OpenGL was.
| pjmlp wrote:
| Khronos APIs are C, DirectX is C++ exposed via COM or WinRT,
| Metal is Objective-C with C++ for shaders and Swift bindings,
| on Nintendo and PlayStation depends on which console generation
| you talk about.
| indy wrote:
| Additionally SDL3 is also C and the most recent version of the
| Box2d physics library was rewritten in C
| torlok wrote:
| I write mostly like I would in C, but use C++ features as needed.
| It ends up looking similar to Rust if you squint. All these "I
| write games in C" people complain about C++ features, and then
| end up reimplementing virtual interfaces manually with struct
| headers or massive switch statements, just to feel better about
| themselves. Writing games in C is not harder, you just have to
| implement modern language features by hand.
|
| Complaining about a language having features you don't want is
| silly. C++ doesn't take longer to compile if you don't abuse
| templates.
| pansa2 wrote:
| Yeah, you could argue that choosing C is just choosing a
| particular subset of C++.
|
| The main difference from choosing a different subset, e.g.
| "Google C++" (i.e. writing C++ according to the Google style
| guide), is that the compiler enforces that you stick to the
| subset.
| ninkendo wrote:
| C's string handling is so abominably terrible that sometimes
| all people really need is "C with std::string".
|
| Oh, and smart pointers too.
|
| And hash maps.
|
| Vectors too while we're at it.
|
| I think that's it.
| teo_zero wrote:
| I agree on the former two (std::string and smart pointers)
| because they can't be nicely implemented without some help
| from the language itself.
|
| The latter two (hash maps and vectors), though, are just
| compound data types that can be built on top of standard C.
| All it would need is to agree on a new common library, more
| modern than the one designed in the 70s.
| uecker wrote:
| why not std::string?
| direwolf20 wrote:
| It's a class, so it doesn't work in C.
| uecker wrote:
| Sure, but you can have a similar string abstraction in C.
| What would you miss? The overloaded operators?
| direwolf20 wrote:
| Automatic memory accounting -- construct/copy/destruct.
| You can't abstract these in C. You always have to call
| i_copied_the_string(&string) after copying the string and
| you always have to call
| the_string_is_out_of_scope_now(&string) just before it
| goes out of scope
| uecker wrote:
| This seems orthogonal to std::string. People who pick C
| do not want automatic memory management, but might want
| better strings.
| direwolf20 wrote:
| Automatic memory management is literally what makes them
| better
| uecker wrote:
| For many string operations such as appending, inserting,
| overwriting etc. the memory management can be made
| automatic as well in C, and I think this is the main
| advantage. Just automatic free at scope end does not work
| (without extensions).
| direwolf20 wrote:
| You can make strings (or bignums or matrices) more
| convenient than the C default but you can never make them
| as convenient as ints, while in C++ you can.
| uecker wrote:
| Yes, but I do not think this is a good thing. A
| programming language has to fulfill many requirements,
| and convenience for the programmer is not the most
| important.
| direwolf20 wrote:
| Empirically it is. All the most used languages are the
| most convenient ones.
| teo_zero wrote:
| You can surely create a std::string-like type in C, call
| it "newstring", and write functions that accept and
| return newstrings, and re-implement the whole standard
| library to work with newstrings, from printf() onwards.
| But you'll never have the comfort of newstring literals.
| The nice syntax with quotes is tied to zero-terminated
| strings. Of course you can litter your code with
| preprocessor macros, but it's inelegant and brittle.
| krapp wrote:
| Hacker News seems not to hate antirez's sds
|
| https://github.com/antirez/sds
|
| https://news.ycombinator.com/item?id=45014911
| pjmlp wrote:
| If only WG14 added something similar to C.
|
| Yes, SDS exists, however vocabulary types are quite
| relevant for adoption at scale.
| tialaramex wrote:
| Because C wants to run on bare metal, an allocating type
| like C++ std::string (or Rust's String) isn't affordable
| for what you mean here.
|
| I think you want the string slice reference type, what
| C++ called std::string_view and Rust calls &str. This
| type is just two facts about some text, where it is in
| memory and how long it is (or equivalently where it ends,
| storing the length is often in practice slightly faster
| in real machines so if you're making a new one do that)
|
| In C++ this is maybe non-obvious because it took until
| 2020 for C++ to get this type - WG21 are crazy, but this
| is the type you actually want as a fundamental, not an
| allocating type like std::string.
|
| Alternatively, if you're not yet ready to accept that all
| text should use UTF-8 encoding, -- and maybe C isn't
| ready for that yet - you don't want this type you just
| want byte slice references, Rust's &[u8] or C++
| std::span<char>
| ninkendo wrote:
| I think a vec is important for the same reason a string
| is... because being able to properly get the length, and
| standardized ways to push/pop from them that don't
| require manual bounds checking and calls to realloc.
|
| Hash maps are mostly only important because everyone
| ought to standardize on a way of hashing keys.
|
| But I suppose they can both be "bring your own"... to me
| it's more that these types are so fundamental and so
| "table stakes" that having one base implementation of
| them guaranteed by the language's standard lib is
| important.
| WalterBright wrote:
| When I developed D, a major priority was string handling. I
| was inspired by Basic, which had very straightforward,
| natural strings. The goal was to be as good as Basic
| strings.
|
| And it wasn't hard to achieve. The idea was to use length
| delimited strings rather than 0 terminated. This meant that
| slices of strings being strings is a superpower. No more
| did one have to constantly allocate memory for a slice, and
| then keep track of that memory.
|
| Length-delimited also super speeded string manipulation.
| One no longer had to scan a string to find its length. This
| is a big deal for memory caching.
|
| Static strings are length delimited too, but also have a 0
| at the end, which makes it easy to pass string literals to
| C functions like printf. And, of course, you can append a 0
| to a string anytime.
| jfaulken wrote:
| Just want to off-topic-nerd-out for a second and thank
| you for Empire.
| WalterBright wrote:
| You're welcome!
|
| One of the fun things about Empire is one isn't out to
| save humanity, but to conquer! Hahahaha.
|
| BTW, one of my friends is using ClodCode to generate an
| Empire clone by feeding it the manual. Lots of fun!
| 9rx wrote:
| Add concurrency and you more or less came up with same list
| C's own creator came up when he started working on a new
| language.
| saidinesh5 wrote:
| And constructors and destructors to be able to use those
| vectors and hash maps properly without worrying about
| memory leaks.
|
| And const references.
|
| And lambdas.
| pjmlp wrote:
| Yeah, WG14 has had enough time to provide safer
| alternatives for string and arrays in C, but that isn't a
| priority, apparently.
| tialaramex wrote:
| The C++ std::string is both very complicated mechanically
| and underspecified, which is why Raymond Chen's article
| about std::string has to explain three different types (one
| for each of the three popular C++ stdlib implementations)
| and still got some details wrong resulting in a cycle of
| corrections.
|
| So that wouldn't really fit C very well and I'd suggest
| that Rust's String, which is essentially just Vec<u8> plus
| a promise that this is a UTF-8 encoded string, is closer.
| klaussilveira wrote:
| https://bkaradzic.github.io/posts/orthodoxc++/
| pantalaimon wrote:
| C is not a subset of C++, there are some subtle things you
| can do in C that are not valid C++
| uecker wrote:
| Some subtle and some not so subtle.
| pjmlp wrote:
| It is when compared with C89, also the ISO C++ requires
| inclusion of ISO C standard library.
|
| The differences are the usual that occur with guest
| languages, in this case the origin being UNIX and C at Bell
| Labs, eventually each platform goes its own merry way and
| compatibility slowly falls apart with newer versions.
|
| In regards to C89 the main differences are struct and
| unions naming rules, () means void instead of anything
| goes, ?: precedent rules, implicit casts scenarios are
| reduced like from void pointers.
| saidinesh5 wrote:
| Linters etc... Validates the subset you're choosing to use
| for your project too.
| randomtoast wrote:
| I've seen this play out a lot. People say they "write games in
| C" and then quietly rebuild half of C++ anyway with vtables in
| structs or giant switch statements, just without the compiler
| helping. That's fine if it makes you happier, but it's not
| obviously simpler or safer. Also, C++ compile times are mostly
| a self-inflicted wound via templates and metaprogramming, not
| some inherent tax you pay for having virtual functions.
| direwolf20 wrote:
| It's important that you do these things yourself before you
| utilise the compiler to do them for you, so you have real
| understanding.
| sandpaper26 wrote:
| This reads like an LLM generated response that simply
| restates the comment it's replying to
| randomtoast wrote:
| Heck the LLM accusations get a bit out of hand lately here
| on HN. I could delve into it now ... but I want to safe our
| time.
| mjburgess wrote:
| A switch statement is how you do ad-hoc polymorphism in C --
| i dont thinks an own against C developers to point that out.
| If they wanted to adopt the C++ style that immediately
| requires the entire machinery of OOP, which is an incredibly
| heavy price to avoid a few switch statements in the tiny
| number of places ad-hoc poly is actually needed
| whizzter wrote:
| You don't usually do C++ subsets if you want the full
| shebang.
|
| I have a "mini-std" headerfile that's about 500 LoC
| implementing lightweight variants of std::vector,
| std::function, a stack-local std::function (unsafe as hell
| and useful as hell to avoid allocations), a shared-ptr,
| qsort and some other nifty stuff.
|
| That does a lot of things, but even then I use other
| patterns that brings a lot of bang for the buck without
| having to go full C (hint: the stack-local function
| equivalent gets a lot of mileage).
| gf000 wrote:
| > but it's not obviously simpler or safer
|
| On top of likely having worse performance.
| uecker wrote:
| I think it is simpler and "the compiler not helping" ==
| "things are more transparent". int a = 3;
| foo(a); // What value has a ?
|
| There are various things one does not have to worry about
| when using C instead of C++. But the brain needs some time to
| get used to it.
| wasmperson wrote:
| I think I get what you're trying to say, but you may have
| picked a bad example, here: #define foo(a)
| a = 12
| uecker wrote:
| Yes, but this is more a theoretical problems while
| references are common in C++.
| pron wrote:
| > Complaining about a language having features you don't want
| is silly.
|
| It might be silly if you're working on your own. Software that
| delivers a lot of value is usually developed and evolved not
| only by team, but by a team with changing members and changing
| leadership over the project's lifetime. The features used will
| be the union of all features used over the years, and while
| it's easy for team leads to allow the use of more features than
| their predecessors, it's quite hard to reduce them.
|
| Also, you may be forced to use language features you don't want
| if they're used by libraries whose functionality you do want.
| For example, when doing low-level programming, I don't like
| implicit calls that I can't clearly see on the page (e.g.
| destructors or overloaded operators). But if libraries I want
| use them, then I'll have those implicit calls. But if the
| language doesn't have those features, libraries obviously won't
| use them.
| karamanolev wrote:
| > It might be silly if you're working on your own.
|
| That's exactly the case when it's easiest. If you don't need
| a feature, just don't use it and case closed. With a team
| it's harder - you have to force/enforce others not to use a
| given feature.
|
| > if they're used by libraries whose functionality you do
| want
|
| If you're using C++ you can just use the C library you
| would've used otherwise, no?
| adastra22 wrote:
| There are linters to do that enforcement automatically.
| Yokohiii wrote:
| > Also, you may be forced to use language features you don't
|
| This is quite important and often overlooked. An annoying
| fallacy is that people think some features are optional, but
| once they get heavily used, they aren't anymore. Often they
| quickly become an requirement and if you don't follow suit,
| your code is legacy or you are an idiot. But well, I guess I
| create legacy code upfront and the cargo cultists create
| modern code that turns into legacy next day.
| etrvic wrote:
| I feel like, for me, it's that I am more familiar with writing
| in C and switching to C++ seems rather difficult. So, sure I am
| reimplementing features that already exist in anoter language,
| it just so happens in this case is C++. Why not use python if
| you want to avoid reimplementing the wheel as much as possible.
| And sure python is not suited for game development but I just
| wanted to make a point with it. I think in the end ising a
| language you are most familiar with results in the most amount
| of enjoyable coding.
| cogman10 wrote:
| For a solo dev, it's not difficult. C++ is nearly a superset
| of C. You don't have to adopt all of C++ to start using it
| and to get immediate benefits from it (for example,
| unique_ptr, shared_ptr, and vector would all be things that I
| think any C dev would really appreciate).
|
| A reason I can think of to not move to C++ is that it is a
| vast language and, if you are working on a team, it can be
| easy for team members ultimately forcing the whole team to
| become an expert in C++ simply because they all will be
| familiar with a different set of C++ features.
|
| But for a solo dev? No reason not to use it, IMO. It's got a
| much nicer standard library with a rich set of datastructures
| that just make it easier to write correct code even if you
| keep a C style for everything.
| pjmlp wrote:
| I learnt C++ on Turbo C++ 1.0 for MS-DOS as teenager, after
| doing C with Turbo C 2.0.
|
| Being on Borland ecosystem that was followed by several
| years of Object Pascal (I was already using TP at the
| time), and C++.
|
| Never got the point of why to keep using C, other than
| external constraints like school assignments, jobs
| requirements or lack of compilers.
| krapp wrote:
| >Writing games in C is not harder, you just have to implement
| modern language features by hand.
|
| I feel like if you need to implement modern language features,
| you shouldn't be using C. The entire point of C is to not be
| modern.
| tomcam wrote:
| > just to feel better about themselves.
|
| Mindread much?
| whizzter wrote:
| Exactly, not even do you need to religiously need stick to your
| subset, separate modules can be using supetsets that import
| useful libraries and if they're used for code that is seldomly
| changed (such as model importers) then the longer compile time
| will only matter for rebuilds and not quick tests.
| petters wrote:
| > C++ doesn't take longer to compile if you don't abuse
| templates.
|
| Surprisingly, this is not true. I've written a C++ file only to
| realize at the end that I did not use any C++ features.
| Renaming the file to .c halved the compilation time.
| levodelellis wrote:
| I don't believe you, I measured compile times in c compilers
| and my own. If you provide more information I'd be more
| likely to believe you
| petters wrote:
| That's fair. I'm unable to provide more information though
| so we'll have to disagree.
| flohofwoe wrote:
| On some compiler toolchains (IIRC MSVC was the main
| offender) you get a lot more code pulled into your source
| file when including a C stdlib header (like <stdio.h>) in
| C++ mode versus C mode. Basically a couple hundred lines in
| C mode versus thousands of lines in C++ mode.
| levodelellis wrote:
| I measured once and to my surprise templates aren't (directly)
| the reason for long compile times. It's function bodies in
| headers, and obviously templates are in headers and they call
| other templated functions/classes which explodes code
| generation and time. But if it's only a few lines and doesn't
| call other templated functions it's likely fine. I wrote about
| it here https://bolinlang.com/wheres-my-compile-time
|
| After writing that, I wrote my own standard library (it has
| data structs like vector, hashmap and sets; slices, strings,
| rng, print, some io functions, and more) which uses a lot of
| templates, and it compiles in <200ms on both clang and gcc.
| Many standard library headers take much longer to compile than
| that. It's not a terrible idea to have your own standard lib if
| you need quick compile times.
| direwolf20 wrote:
| Your website seems to be blocking Tor
| levodelellis wrote:
| Oh? I use a boring old $5 VPS (using nginx for https).
| There's no cloudflare or anything else involved. I wonder
| why that's happening. I may look into that this week
| direwolf20 wrote:
| It could also just be down. I didn't try outside of Tor
| rustyhancock wrote:
| Another option can be if you have a core set of headers your
| project will use (and is stable) just precompiling them.
| HoldOnAMinute wrote:
| It's possible to use only a subset of the language. You could
| write a Java program without classes if you really wanted to.
| Just put the whole thing in main().
|
| A lot of smart people pick and choose what they want from the
| language, just like religion, they keep the good parts and
| discard the bad.
| direwolf20 wrote:
| main is also in a class in Java.
|
| Even with the recent extension where it looks like it isn't,
| the compiler adds one for you.
| bobajeff wrote:
| I remember the creator of Kaiju engine stating something about
| C++ compilers producing slower code with C-style C++.
| direwolf20 wrote:
| That's probably to do with exceptions -- possibly the only
| thing that pervades C++ code even if you don't use it. The
| compiler has to write code so an exception at any point
| leaves the stack in a sensible way, etc. Try -fno-exceptions
| (and -fno-rtti might save some memory while you're at it)
|
| Regrettably not _every_ C++ feature is free if you don 't use
| it. But there aren't many that aren't.
| wasmperson wrote:
| For every person who says on the internet that you can just use
| a C++ subset, there's another who insists that C is the _bad_
| C++ subset. So compiling C code with a C++ compiler promotes
| your code from "good C code" to "bad C++ code" (most C code
| isn't "exception safe," for example).
|
| It's arguably irrational to evaluate a language based on this,
| but you can think of "this code could be better" as a sort of
| mild distraction. C++ is _chock full_ of this kind of
| distraction.
| feelamee wrote:
| Of course people do" virtual functions" in C, but I think this
| is not an argument despite C. I noticed that making virtual in
| C++ is sooo easy that people start abusing it. This making
| reading/understanding/debugging code much harder (especially if
| they mess this up with templates). And here C is a way - it
| allow but complicates "virtual". So, you will think twice
| before using it
| pjmlp wrote:
| Most operating systems written in C have it all over the
| place.
|
| Drivers, and extension points for userspace.
| card_zero wrote:
| C++ reimplements a lot of the things we do in C with function
| pointers, while hiding what's actually happening behind
| topheavy syntax that implies a 1990s object oriented paradigm
| that's dead now.
| direwolf20 wrote:
| Contrary to popular belief C++ isn't really object-oriented.
| I mean, you can write object-oriented code, but the language
| doesn't make assumptions about what goes into a class. It's
| really just a struct with associated functions.
| Yokohiii wrote:
| That's an odd opinion about a language with a lot of class
| related features. I can only assume you have a very strong
| definition of OOP.
| direwolf20 wrote:
| OOP doesn't mean that your language has a "class"
| keyword, nor dot notation for calling functions.
| afiori wrote:
| I enjoyed the pragmatic historical definition of OOP
| given in https://www.youtube.com/watch?v=wo84LFzx5nI
| where essential it can be seen as subtype polymorphism
| flohofwoe wrote:
| > It's really just a struct with associated functions.
|
| If that were actually true C++ would be a lot easier to
| accept as a 'C successor'. Instead you have the implicit
| this-pointer, complicated rules for which constructor or
| operator overload is actually called, a hidden vtable
| pointer (not to mention multiple inheritance), then you
| have public/private/protected, override vs final, const
| methods (which wouldn't be needed as a separate syntax
| feature if the this arg wouldn't be implicit) etc etc
| etc... that a lot of OOP-baggage which a lot of C++ coders
| probably don't even notice anymore.
|
| A plain C struct with function pointers does indeed make a
| lot more sense than all the OOP-ism that C++ hides from you
| ;)
| direwolf20 wrote:
| It has lots of optional features, none of which make it
| an object-oriented language. It's an _everything_
| -oriented language. It has lambda syntax for functors,
| but you're not calling it an impure-functional
| programming language. Virtual functions are one feature,
| which is useful in pseudo-object-oriented code.
| vadersb wrote:
| how is OOP dead if tons of code keep being written using OOP
| these days? From anything corporate in Java/C# to Hyprland
| C++
| tialaramex wrote:
| > then end up reimplementing virtual interfaces manually
|
| C++ dynamic dispatch (your "virtual interfaces") is achieved by
| welding a vtable onto every type and providing a pointer to
| that vtable for instances of the type. If in 90% of your code
| you deal with specific types like Goose or Swan or Duck or
| Seagull, and only 10% needs to work with the broad Bird
| category well, too bad, every Goose, Swan, Duck and Seagull
| carries around that vtable pointer even if it goes nowhere near
| that 10% of the system. This way your Bird code "just works" in
| C++.
|
| That's not the only way to crack this nut. Idiomatic Rust
| approach uses vtables only in the Bird code, elsewhere they
| don't exist, and thus don't take up space in a Duck or whatever
| that's always a Duck, but in exchange now you're spending more
| time thinking, because by default there aren't any vtables and
| so dynamic dispatch isn't possible at all.
|
| So while that C programmer has to implement features by hand,
| they are at least able to specifically implement the feature
| they wanted, not whatever was easiest for Bjarne Stroustrup
| last century.
| agentultra wrote:
| C++ nudges you to think in terms of single elements. Operator
| overloading, ctors/dtors, references, etc. you pay that cost
| all over the place.
|
| C programs tend to nudge you into thinking in terms of arrays
| of data.
|
| For game development you generally want to think this way.
| The cost of vtables and all the cache misses doesn't have to
| be paid. A game has to stream bytes. Many things at once.
| Rarely single elements at a time.
| pjmlp wrote:
| Only if devs lack the skills to understand what to actually
| use.
|
| There is this anti-C++ bias that keeps forgetting that
| using C++ doesn't mean use every feature.
|
| Just like many keep using C as if C89 was latest, and never
| adopt anything added in the last 30 years.
| avadodin wrote:
| What this comment looks like to a C programmer:
|
| >> C89
|
| > agree :D
| agentultra wrote:
| I agree, there is a nice language buried in all the
| features trying to escape.
|
| The struggle is that if you choose a subset of the
| language to use and you have dependencies... well you're
| including whatever features they use into your subset.
|
| I don't think C++ is a bad language at all or anything.
| Just that it nudges developers into certain modes of
| thinking based on the features it chooses to focus on.
| Might explain why some developers still choose C.
| Panzerschrek wrote:
| > by welding a vtable onto every type
|
| It's not true. Virtual methods table is present only for
| classes with at least one virtual method. Learn C++ properly
| before doing such claims.
| tialaramex wrote:
| The context you snipped is about dynamic dispatch, that is
| what you - as someone who has "learned C++ properly"
| apparently call "classes with at least one virtual method"
| and indeed the earlier comment calls "virtual interfaces".
| pjmlp wrote:
| Except that C++ provides the tools to do just like C, Rust,
| or whatever one feels like doing for dispatching, even if it
| requires a few pages of template metaprogramming mixed with
| compile time executions, or writing exactly the same C code
| on the common subset across both languages.
|
| Now with reflection even more tools will be available.
|
| Which is why despite all its warts and security flaws, many
| inherited from C source code compatibility, many domains will
| keep using it, because they will complain about their missing
| 1% that no one else uses.
| tialaramex wrote:
| Because these are General Purpose languages you _can_ do
| the same things, but the contrast here is what 's provided
| in the box and how it is used idiomatically, because in
| practice that's what gets used, and that's what I explained
| above.
|
| You _can_ write C++ style OOP hierarchy code in Rust but
| that 's not idiomatic, and you can write Rust style
| explicit dynamic dispatch in C++ but again it isn't
| idiomatic.
| pjmlp wrote:
| Microsoft uses Rust like traits on Windows with C++.
| torlok wrote:
| The convenience of having regular generics and dyn generics
| handled automatically is a great feature of Rust, sure,
| however you can write a template in C++ that directly calls a
| method, f.e. obj.Object::method(), which skips the vtable,
| achieving the same thing. Or you can keep manually writing
| everything in C because you refuse to learn C++.
| Suppafly wrote:
| >C is not harder, you just have to implement modern language
| features by hand
|
| That's definitely harder.
| lelanthran wrote:
| > Complaining about a language having features you don't want
| is silly.
|
| If your criteria for a good language is "how many features does
| it have", then sure, C++ wins. OTOH, if you criteria is "How
| many footguns does the language have" then C++ loses to almost
| every other mainstream language, which includes C.
|
| Sometimes the _lack_ of footguns is a plus.
| jamienicol wrote:
| Surely your criteria should be some combination of the two
| (plus other factors). C may have fewer footguns than C++, but
| it still has many, whilst also lacking many useful features
| lelanthran wrote:
| > Surely your criteria should be some combination of the
| two (plus other factors).
|
| Sure, but the weighting would be different for different
| people.
|
| > C may have fewer footguns than C++, but it still has
| many, whilst also lacking many useful features
|
| We are not talking "2 fewer footguns", or "5 fewer
| footguns"; we are talking "dozens fewer footguns".
|
| When I need a language with more features than C, I _don
| 't_ choose C++, because the choice is not "Use C for
| simplicity, and use C++ to trade simplicity off against
| features", it's usually "Use C for simplicity, and use
| Java/C#/Go/Rust for features".
| flohofwoe wrote:
| > C++ doesn't take longer to compile if you don't abuse
| templates.
|
| It actually does though, unless you also drop C++ stdlib usage
| completely (have you looked at how many lines of code just
| <vector> alone pulls into each source file? - it's upward of
| 20kloc and growing with each new C++ version).
|
| And at that point you get into discussions with various C++
| camps about why you don't use the C++ stdlib and instead prefer
| to reinvent the wheel (and this friction with other C++ coders
| is the main problem of carving out your own subset - it works
| ok in complete isolation, but software development work hardly
| happens in splendid isolation and even then you'd might to want
| to use C++ libraries written by other people from time to
| time...)
|
| And once you've been dragged into such C++-subset-discussion
| month after month, year after year, at _that_ point it is
| _much_ less exhausting to just write plain C. And the C
| community (if it can be called that) seems to be much less
| concerned about coding style dogma and generally a nicer bunch
| to interact with.
|
| FWIW, I switched around 2017 and each time I have to interact
| with a C++ library for lack of alternatives it's usually not a
| pleasant experience (with the notable exception of Dear ImGui -
| but even there I started to prefer the C bindings so that I
| don't need to strictly separate the UI code from the rest of
| the code base, which sometimes makes sense, but often not,
| especially with an immediate mode UI framework).
| patrick451 wrote:
| At least you can read the switch statement. One of the worst
| features of c++ is all of the code that gets generated for you
| automatically.
| akoluthic wrote:
| It's not unheard of, but you have to be a little crazy to do this
| in 2026. I developed Chrysalis entirely in C (with GLFW3 and FMOD
| for audio): https://store.steampowered.com/app/1594210/Chrysalis/
| trueno wrote:
| I've been working religiously for like 2 years on the jedi
| academy codebase which is c & c++. It's Ravensofts variant of
| the idtech3 engine and it's insane how fragile the games combat
| is to precision and timing changes, I can't get away with
| adding much without destroying the lightsaber combat qualities.
| There are certain spots where I can't even add an incrementing
| i++ counter lmao it presents just enough of a slowdown or
| shifts something around that I haven't been able to track down
| that bleeds into the rest of the gameplay, but I am also
| sticking with the ancient compilers from 22 years ago so as to
| preserve the fpu characteristics of the game. There are some
| modern attempts at using this codebase with modern tooling but
| they've kind of bastardized/refactored all of it and it just
| feels different/unbalanced wrong. idtech3 is such an incredibly
| foray into c it's really something else and carmack and team
| really sent it back in the day.
| lylejantzi3rd wrote:
| Are you working on the original codebase or the OpenJK fork?
| trueno wrote:
| original codebase
| ethin wrote:
| I write all of my games in pure C++. C++ all the way. FMOD for
| the audio engine, Steam Audio or Atmoky TrueSpatial for
| HRTF/geometric occlusion, and Jolt Physics for, well, physics.
| I'm sure many might say I'm a bit insane to do that, but eh, I do
| it anyway because it's fun.
| mapcars wrote:
| >I really dislike javascript, it is so loose that I marvel that
| people are able to write big chunks of software in it. I have no
| interest in trying.
|
| Because they use Typescript.
|
| >The stop-the-world garbage collection is a big pain for games
|
| There is a number of languages that allow manual memory
| management: Zig, Nim, Rust and few others
| archargelod wrote:
| > There is a number of languages that allow manual memory
| management: ... Nim
|
| Nim not only has support for manual memory management, but
| there're several gc modes that are not stop-the-world.
|
| Also, since Nim 2, the stdlib now is using ARC by default,
| which is deterministic and has advantages over conventional
| garbage collection.
| pjmlp wrote:
| People did do that, 30 years ago.
|
| Then Watcom C/C++ made it quite easy to use C++ for game
| development on PCs, PlayStation 2 introduced support for C++,
| quickly followed up by XBox and Nintendo, and that was it.
| kahlonel wrote:
| Wrong. I'm still doing it.
| pjmlp wrote:
| Linux kernel also keeps using C.
| HeavyStorm wrote:
| Yes, C. Like all id games up to... Doom 3, if I'm not mistaken?
| Only then they switched to C++. There's absolutely nothing
| impressive about this fact.
| brokencode wrote:
| Nobody claimed it was impressive. It's a little unusual to use
| C instead of C++, but that's about it.
| direwolf20 wrote:
| It's impressive these days when software quality and
| craftsmanship is declining.
| quotemstr wrote:
| Plenty of people cycle on a fixie too. So what? C, especially
| modern C, _does_ provide metaprogramming and abstraction
| facilities. In practice, you can even get things like the
| "defer" construct from other languages:
| https://lwn.net/Articles/934679/
|
| The question isn't "Can I write a game in C?". Yes, of course you
| can, and it's not even _that_ painful. The question is "Why
| would you?", and then "Why would you brag about it?"
|
| > C++ covers my needs, but fails my wants badly. It is
| desperately complicated. Despite decent tooling it's easy to
| create insidious bugs. It is also slow to compile compared to C.
| It is high performance, and it offers features that C doesn't
| have; but features I don't want, and at a great complexity cost.
|
| C++ is, practically speaking, a superset of C. It being
| "complicated"? The "insidious bugs"? It being "slow to compile"?
| All self-inflicted problems. The author of this article can't
| even fall back on the "well, my team will use all the fancy
| features if I let them use C++ at all!" argument pro-C-over-C++
| people often lean on: he's the sole author of his projects! If he
| doesn't want to do template metaprogramming, he... just doesn't
| want to do it.
|
| I don't read these sorts of article as technical position papers.
| People say, out loud, "I use C and not C++" to say something
| about _themselves_. ISTM that certain circles there 's this
| perception that C is somehow more hardcore. Nah. Nobody's
| impressed by using it over a modern language. It really is like a
| fixie bicycle.
| enricotr wrote:
| "Practically speaking" means nothing. Use "from my confused
| point of view", instead.
| quotemstr wrote:
| If GDB could switch its C codebase to compiling as C++
| without major surgery, it's close enough.
| wudangmonk wrote:
| If he doesn't use C++ features then there's no point of
| bothering with C++ at all. C++ is kinda but not really a
| superset of C. There are some nice features that are lacking in
| C++.
|
| The fixie example wants to make the comparison that using C
| instead of C++ is deliverately done just to brag about doing
| something in a way that is more difficult than in should be. In
| reality the issue is that C++ might not offer you any benefit
| at all and it could potentially bring you issues later on for
| things such as interfacing with other languages.
|
| I personally do not see the point of using C++ if you do not
| use any of its features.
| direwolf20 wrote:
| Usually you start with just one feature, like std::map
| instead of OpenSSL's abomination of a hashmap library or
| rolling your own.
|
| Of course you should use std::unordered_map instead of
| std::map because the latter is actually a treemap, but you
| probably don't know that when you first learn it...
| its_magic wrote:
| Nah, I prefer to just use C, because at least I can parse
| the quite sane and helpful error diagnostics when I omit a
| semicolon or something, instead of getting 15 pages of
| unreadable garbage dumped into my lap by the oh-so-
| wonderful C++ standard library.
|
| (Which quite frankly isn't much of a "standard" when
| there's about a dozen different real world interpretations
| of the code depending on which flavor of which compiler
| from which year that you're using.)
|
| I also don't have to wait eons for my code to compile.
| Really, the mental and computational load of C has got to
| be 1/10 of C++.
|
| What a nightmare C++ is, and it just keeps getting worse
| every year thanks to the incompetent standards committee.
| direwolf20 wrote:
| LPT: scroll up to the top of the error message. Typically
| it's "could not match this function call" followed by
| "here's all the things that might match and why they
| don't match"
| its_magic wrote:
| > I don't read these sorts of article as technical position
| papers.
|
| I do.
|
| > People say, out loud, "I use C and not C++" to say something
| about themselves.
|
| Just like you are telling us something about yourself right
| now.
|
| > ISTM that certain circles there's this perception that C is
| somehow more hardcore.
|
| That's not why we use it.
|
| There are certainly many _noobs_ who think C is hardcore. That
| just goes to show how low the bar has fallen since the masses
| rushed into computing.
|
| Many of these people also think of changing their own oil or a
| flat tire as being a superpower. Some could not identify the
| business end of a screwdriver if their life depended on it.
| Their opinion on the relatively difficulty or impressiveness of
| anything is to be taken with a huge grain of salt.
|
| There are many good reasons to use C. If nothing else it
| demonstrates that the user is a free thinker and not a fucking
| muppet. It's the sort of thing that attracts _me_ and drives
| _you_ away. That 's valuable.
|
| > Nobody's impressed by using it over a modern language.
|
| 1) The word "modern" is not a magic talisman that makes
| anything it's attached to automatically worthy.
|
| 2) "Nobody" does not mean what you apparently think it means.
| Free clue: others exist in the world beside yourself and your
| self-absorbed clique.
|
| 3) Nobody with a brain is impressed by whatever the midwits are
| doing. Anyone who can fog a mirror can follow the herd off the
| nearest cliff. It's the outliers who are impressive.
|
| 4) Technically anything since the 1500s is "modern." It's such
| a vague, useless word that serves no purpose other than
| "virtue" signalling.
|
| C++ is fucking garbage. Always has been. Keeps getting worse
| and worse every year. Enjoy your PAGES full of indecipherable
| gibberish ("error diagnostics"), your miserably slow compile
| times, and your closet full of footguns and decades old sticks
| of sweating dynamite. Slowest language by far, other than the
| _so very modern_ abomination that is Rust. You can keep it.
| lelanthran wrote:
| > People say, out loud, "I use C and not C++" to say something
| about themselves. ISTM that certain circles there's this
| perception that C is somehow more hardcore.
|
| Sounds like this is just you projecting.
|
| Almost _any_ language has fewer footguns than C++, and thus
| programmers will take almost anything else over C++.
|
| It's just incidental that "anything else" also includes C.
| quotemstr wrote:
| > I like Go a lot. In many ways it is C revisited, taking into
| account what has be learnt in the long years since it was
| released. I would like to use it, but there are big roadblocks
| that prevent me. The stop-the-world garbage collection is a big
| pain for games, stopping the world is something you can't really
| afford to do.
|
| I'm no Go fan, to be clear, but GC isn't the problem with Go. It
| has a pretty decent GC with sub-millisecond pause times. People
| who complain about GC pauses while extolling the virtues of
| manual memory management are running on a set of prejudices from
| 1999 and are badly in need of a mental firmware update.
| nasretdinov wrote:
| Yeah I was a bit surprised by this too. I think the post was
| written around 10 years ago, when it still was a genuine
| problem in Go.
| quotemstr wrote:
| Good eye. This is why HN titles have year tags. :-)
|
| Yeah, this is from 2016. I don't think choosing C over C++
| was defensible even back then, but the critique of Go makes
| more sense now.
|
| https://web.archive.org/web/20160109171250/http://jonathanwh.
| ..
| carefree-bob wrote:
| The performance gains from bit-level control over memory come
| from managing the layout to ensure cache locality and do things
| like SIMD - and nowadays even GPU kernel offload. Enormous
| performance gains.
|
| I agree that it really isn't about garbage collection pauses,
| but I haven't heard people focusing on "eliminating gc pause"
| when they talk about low level languages, but they spend a lot
| of time talking about SIMD, GPU kernels, and cache misses. If
| Go could add these features, it would be a performance monster.
| nasretdinov wrote:
| Go defines structs the same way C does, so it's already
| encouraging thinking about and optimising the physical data
| layout. It also recently added experimental support for SIMD
| intristics: https://go.dev/doc/go1.26#simd . Nothing on GPU
| side yet though, but I wouldn't be surprised to see it there
| eventually too :)
| carefree-bob wrote:
| Yes, I know Go's structs are similar to C in terms of
| syntax, but does the Go compiler guarantee the same bitwise
| layout for its data structures? Most GC languages add
| metadata to the data structures to track GC status, and
| this changes both the memory layout and the word alignment,
| which then sometimes forces the language to add extra
| padding to maintain alignment. And this nests as you put
| one struct inside another, or an array inside a struct.
|
| Now you have "fat arrays" and "fat structs", so instead of
| grabbing a pointer and loading the next 128 bits into
| memory and doing an operation, you have to grab the
| pointer, read out data from individual elements, combine
| them, create a new element with the combined data, and then
| you have a 128 bits. But even then, you don't know whether
| you have 128 bits or not. Some gc-specific metadata might
| have been added by the compiler (and probably was).
|
| Bottom line, it's very hard in the GC world to have bit-
| wise control over memory layout, even if user-level syntax
| of "structs" is the same. And one consequence of that is
| that you can't just "do" SIMD in Go. You have to wait for
| Go to expose a library that does this for you, and you will
| always be limited by what types of unpacking/repacking the
| language designers allowed you to do.
|
| Or, you are stuck with hoping the compiler is very smart,
| which is never the case and requires huge compile times for
| marginal gains in compiler smarts.
|
| So it's not about GC collection pauses so much as no longer
| having access to memory layouts.
| nasretdinov wrote:
| > does the Go compiler guarantee the same bitwise layout
| for its data structures
|
| It probably won't be fully 1:1 with C, but it's good
| enough that you can write code like this and it works: ht
| tps://github.com/fsnotify/fsnotify/blob/main/backend_inot
| i... (unix.InotifyEvent is just a Go struct:
| https://pkg.go.dev/golang.org/x/sys/unix#InotifyEvent)
|
| > Now you have "fat arrays" and "fat structs", so instead
| of grabbing a pointer and loading the next 128 bits into
| memory and doing an operation, you have to grab the
| pointer, read out data from individual elements, combine
| them, create a new element with the combined data, and
| then you have a 128 bits.
|
| That is not how it works, you get real pointers that you
| can even do math with using unsafe package.
|
| > Most GC languages add metadata to the data structures
| to track GC status, and this changes both the memory
| layout and the word alignment, which then sometimes
| forces the language to add extra padding to maintain
| alignment
|
| Go GC uses a separate memory region to track GC metadata.
| It does not embed this information into structs, arrays,
| etc, directly.
|
| > And one consequence of that is that you can't just "do"
| SIMD in Go. You have to wait for Go to expose a library
| that does this for you, and you will always be limited by
| what types of unpacking/repacking the language designers
| allowed you to do.
|
| You very much could, thanks to what I described above.
| You'll have to write assembly (Go supports assembly), and
| it's even used in some e.g. crypto libraries not just for
| performance reasons, but to ensure constany-time
| operation too.
|
| The downside of using assembly is that it doesn't support
| inlining, and there's a small shim to keep ABI backwards
| compatible with the original way functions were called
| (using stack, whereas newer ABI uses registers). So you
| need to write loops in assembly too to eliminate the
| function call overhead. The SIMD package solves this
| issue by allowing code inlining.
| pyrolistical wrote:
| I always liked C. I enjoyed how brutal it is, except the
| preprocessor.
|
| This is why zig is a godsend. It is actually simpler than C while
| being more precise than C!
|
| For example zig can distinguish between a pointer to a single
| element vs a pointer to an array of unknown length. Where as in c
| abi, it is all T*
|
| When importing a c lib, you can make it more ergonomic to use
| than c itself.
|
| Being able to easily import c lib is especially important to game
| dev, as practically all so called c++ libs also export a c header
| as they know how important it is.
|
| https://github.com/zig-gamedev has a lot of repos of ziggified c
| libs used in games.
|
| As for the preprocessor, zig comptime is so much better. It's
| just more zig that runs at compile time.
| dualogy wrote:
| > as practically all so called c++ libs also export a c header
| as they know how important it is
|
| In the gamedev space, I'd say too few of them do.
| p0w3n3d wrote:
| C has very low entry level, providing that you have some
| knowledge about memory management. When, as a Java developer, I
| had to quickly deliver some exchange connector using given .h and
| .so, I chose C, because C++ had too high entry level. If C is a
| sharp knife, C++ is a rotating pell post full of sharp knives.
| You can cut yourself even if you think you're safe.
|
| But I find string management in C awful and would like to borrow
| it from C++. Only the string management
| direwolf20 wrote:
| That's the neat thing about C++. You don't have to use any of
| it that you don't want to.
| IshKebab wrote:
| That's only really true for solo projects. For example I
| worked in a company on a C++ SDK for a while and it was
| written by one of those clever people who has zero taste in
| software development and thinks you have to use GoF patterns
| _everywhere_. The god object was a CRTP inheriting from about
| 20 templated base classes.
|
| I spent about a year trying to sort out that mess and then
| quit.
|
| To be clear I would still always pick C++ over C because C
| makes simple stuff (strings and containers mainly) waaaay
| more painful than they should be. But I also don't really
| agree with the "C++ is simple - just don't use the complex
| bits!" argument.
|
| Anyway it's kind of academic now because 99% of the time Zig
| is an obviously better choice than C and Rust is an obviously
| better choice than C++.
| andai wrote:
| (2016)
| Bengalilol wrote:
| I did read the whole article thinking "who is he, his name
| reminds me something, but why isn't he providing game names?" and
| so on. Then I clicked on "back to main site". Revelation. A lot
| of his games are jewels. I have a special thing/relation with
| Sportsfriends. So many hours of fun while playing with my son.
| Mikhail_Edoshin wrote:
| I want to write general apps in C. Such as a raster image editor.
| I have some idea and C has exactly the right mix of simplicity
| and flexibility that I need. C is a constructor, and as a
| constructor it places few limits on what you can do. Other
| environments are way more rigid. E. g. I find Python way too
| rigid compared to C.
| seabrookmx wrote:
| GTK apps can be written in pure C. GTK itself is.
| guerrilla wrote:
| As a hardcore C programmer and zealot myself... How in the hell
| can you be productive like that? C is a systems programming
| language, not an application programming language, let alone
| relevant to the levels of abstraction you'd want in game
| development.
|
| That said, "I am dead" is a very real video game indeed... and
| his arguments are very sound. I also can't stand C++. I disagree
| with him on Java though. The core language of Java is actually
| super simple, like C.
| giancarlostoro wrote:
| Were not most games back in the day in C?
| pantalaimon wrote:
| Quake and Doom sure come to mind
| bowsamic wrote:
| Most games back in the day were written in assembly
| guerrilla wrote:
| Back in what day? Quake II I would say is the best good
| looking thing written in pure C. id Tech 3 is partly C++.
| Everything after that era was pretty much C++. Even GoldSrc
| is partly C++. Source was pure C++.
| giancarlostoro wrote:
| I guess back in my day, early to mid 90s. My understanding
| is C became more common.
| guerrilla wrote:
| Well I guess that was my time too but it was kind of a
| very short period. We went from assembly to C++ pretty
| quickly. Like things were assembly for a very long time,
| and they have been C++ for a very long time, but C was
| dominant mostly in that Doom to Quake II window.
| tuhgdetzhh wrote:
| I think the productivity question hinges on what you count as
| the language versus the ecosystem. Very few nontrivial games
| are written in "just C". They are written in C plus a large
| pile of bespoke libraries, code generators, asset pipelines,
| and domain-specific conventions. At that point C is basically a
| portable assembly language with a decent macro system, and the
| abstraction lives outside the language. That can work if you
| have strong architectural discipline and are willing to pay the
| upfront cost. Most teams are not.
|
| I agree on C++ being the worst of both worlds for many people.
| You get abstraction, but also an enormous semantic surface area
| and footguns everywhere. Java is interesting because the core
| language is indeed small and boring in a good way, much closer
| to C than people admit. The productivity gains mostly come from
| the standard library, GC, and tooling rather than clever
| language features. For games, the real disagreement is usually
| about who controls allocation, lifetime, and performance
| cliffs, not syntax.
| guerrilla wrote:
| > I agree on C++ being the worst of both worlds for many
| people. You get abstraction, but also an enormous semantic
| surface area and footguns everywhere.
|
| Not only that, but who even knows C++? It keeps changing.
| Every few years "standard practice" is completely different.
| Such a waste of energy.
|
| > Java is interesting because the core language is indeed
| small and boring in a good way, much closer to C than people
| admit.
|
| I know. I used to be a Java hater, but then I learned it and
| it's alright... except the whole no-unsigned-integers thing.
| That still bothers me but it's just aesthetic really.
| nayuki wrote:
| > no-unsigned-integers [...] still bothers me
|
| I like the lack of unsigned integers in Java. It simplifies
| the language while only removing a tiny bit of
| functionality. You can emulate almost all unsigned math
| using signed operations, whether you use a wider bit width
| or even the same bit width. The only really tricky
| operations are unsigned division and unsigned
| parseInt()/toString(), which Java 8 added to smooth things
| over.
|
| https://www.nayuki.io/page/unsigned-int-considered-
| harmful-f...
| 1718627440 wrote:
| The reason for using unsigned is not that some operations
| need it, it is so to declare a variable that can't be
| negative. If you don't have that, then you must check for
| a negative number in every single interface.
| Andrex wrote:
| > The core language of Java is actually super simple, like C.
|
| Not being facetious, but couldn't you say that about almost any
| language? What makes you say it about Java?
| direwolf20 wrote:
| I'm not sure you could say it about C++, Scala (Java's C++)
| or Rust?
| direwolf20 wrote:
| You have to try it. You can write anything you want in C. Or
| assembler. It's hardly going to be _very_ productive but...
| productivity is greater than zero, and the more you try the
| better you get. Rollercoaster Tycoon was written by hand in
| assembly, as were all NES and SNES games including ones like
| Earthbound and A Link to the Past -- and SNES assembly isn 't
| nearly as nice as x64.
| uecker wrote:
| Ah, the C++ guy who think you need all the features of C++ to
| be efficient... Many people of people are super productive in
| C. There is a cost, but this is usually just some initial
| overhead to identify / write some libraries. In a larger
| project this initial overhead is irrelevant.
| direwolf20 wrote:
| If someone is using a C++ feature it's because they think
| the feature is better than not using it. std::string lets
| you treat strings as easily as ints -- subject to a run-
| time cost. You can make libraries that make strings easier
| to use in C, but you can't make one that makes them as easy
| as ints.
| uecker wrote:
| But it does not have to be "as easy as int" to be able to
| be productive in C. Almost as easy is sufficient.
| direwolf20 wrote:
| It's not almost.
| tombert wrote:
| I've been writing a good chunk of C lately for some stuff that
| has some relatively high memory constraints (lower than I could
| squeeze out of GraalVM).
|
| I know I could do C++, and you could argue that's better, but I
| find C++ to be exceptionally irritating to use. Every time I've
| used C++ I get people telling me I'm using it "wrong", sometimes
| in contradictory ways. Sometimes I should use a "friend"
| function, sometimes "friend functions are evil". Sometimes
| multiple inheritance is fine, sometimes it should be avoided like
| the plague. Sometimes you should "obviously" use operator
| overloading, sometimes you should avoid it because it's confusing
| because you don't know which functions are being called.
|
| I'm sure someone here can "educate" me with the best practices
| for C++, and maybe there will be some reasoning for it, but
| ultimately I don't really care. I just found the language
| annoying and I don't enjoy using it. I know that I could "just
| write it mostly like C and use the C++ features when I need it",
| but I have just found that I have more fun thinking in pure C,
| and I've kind of grown to enjoy the lack of features.
|
| Maybe it's just a little bit of masochism on my end, but I like
| the fact that C gives you so little. You kind of have to think
| about your problem at a very fundamental and low level; you have
| to be aware of how memory is allocated and deallocated, you don't
| get all these sexy helper functional-programming constructs,
| strings aren't these simple automatic dynamic things that you
| have in basically every other language. You have a dumb, simple
| language that will give you exactly what you need to write
| programs and very little else.
|
| Most stuff I write uses a garbage collector, but the safety and
| easy of writing stuff with garbage collectors like Java makes it
| very easy to be lazy. I've grown to appreciate how much C makes
| you actually think about problems.
| howToTestFE wrote:
| Has anyone got any good resources for something like this? I
| haven't touched C in years, and never worked on anything game-
| like. But it does look like a really interesting project to start
| something like this.
| anatoly wrote:
| raylib is one possible starting place. Also might look at dos-
| like (https://mattiasgustavsson.itch.io/dos-like).
| lylejantzi3rd wrote:
| If you have patience, the first 30 or so episodes of Handmade
| Hero are pretty good.
|
| https://guide.handmadehero.org/code/
| krapp wrote:
| Handmade Hero is a bad idea for anyone wanting to learn how
| to make a game in C or C++. Casey intentionally avoids using
| standard libraries and frameworks and his irrational hatred
| of high-level code and modern standards will lead developers
| astray and waste their time.
|
| Even if you're using C you don't need to implement your own
| renderer or do half the things he does. Get a library like
| SDL3 to handle the basics, maybe use Lua/LuaJIT for
| scripting. Learn OpenGL or Vulkan. Stay away from HH and
| Casey Muratori until you're experienced enough to tell the
| difference between his wisdom and his bullshit.
| lylejantzi3rd wrote:
| We'll have to agree to disagree on this one.
| ddtaylor wrote:
| I need RAII and refuse to debug ugly macros as a workaround. The
| STL isn't perfect but it's a good guiding principle.
| direwolf20 wrote:
| You should try writing something serious in C just for the hell
| of it. And without RAII-like macros. Write all your allocs and
| frees.
| csb6 wrote:
| Yes, having built-in generic containers and algorithms is the
| part that keeps me favoring C++. Bespoke versions of these can
| always be written in C (and work fine) but C++ makes it much
| easier and saves time. Lambdas and function objects are also
| useful.
| zuluonezero wrote:
| Nice looking games though.
| JamesTRexx wrote:
| I'm pulling apart and rewriting so far a little in C a personal
| fork of OpenTTD 12.2. I began on it a few years ago for the first
| time for the heck of it after patching for realtime, began again
| while adding features I wanted until I hit a bad enough snag, and
| now began again by first extracting most used functions and
| profiling with Valgrind inbetween.
|
| Things I noticed are inconsistent coding styles, overly complex
| processes, unused(!) functions, inefficient data use, nothing
| surprising with a project worked on by various people in their
| spare time and their own ideas on how to code. And this isn't
| even talking about later versions. To me it's an example of how
| unrestricted access to bling features causes a mess.
|
| Eventually I want it converted to C (C23), split apart in
| seperate functions with a decent source code organisation, and
| simplified processes to make it easier to understand what's going
| on and extend fuctionality. For this I need it simplified as
| possible and weed out the layer of complexity caused by C++
| first. Going to take plenty of time, but I'm still having fun
| doing it (most of the time anyway :-p ).
|
| I'm not advocating anything, but it's satifying to me to bring
| clarity to code and see small improvements to performance during
| the process at the same time. It also gave me an opportunity to
| develop a unique syntax style that visualises parts of the code
| better for me.
| uecker wrote:
| This is great! This so rare that people remove the complexity
| again that has accumulated over the years. Most of the
| programming world is just accumulating entropy and then people
| give up and start fresh at some point, which is just sad.
| teunispeters wrote:
| I like C. You can take away all memory management (yes, including
| some of the unsafe glibc calls that have hidden memory
| management) and everything can be so smooth and clean. Since
| rules like MISRA require up-front allocation - if any is in use -
| this can be tightly controlled.
|
| Very useful if you don't want (or need) surprises anywhere. Or if
| you want all the surprises (exceptions, errors, etc) all better
| tied to the hardware that provides such.
|
| It's also fairly easy to write unit tests for everything.
| parasti wrote:
| What does "vanilla C" mean? Asking as a maintainer of 20 years of
| a game written in C.
| nottorp wrote:
| Btw, in the wannabe indie gaming scene it doesn't matter what
| language or tool or framework you use. It matters if you finish
| the fucking thing.
| zzo38computer wrote:
| I also use C, for games and other stuff. However, for many games
| it can be useful to have a game engine, which is written in C
| (and I might write it by myself) but other parts will be written
| in the game engine. I also sometimes program games on DOS, and
| will use BASIC or Pascal. You will then not need to have too many
| dependencies; if it is a DOS program then the executable file
| should just work (with emulation if necessary) without the mess
| that is common on modern computers.
| globalnode wrote:
| this is refreshing. personally i do all my hobby stuff in C or
| Python. I could certainly use c++ if i wanted to but templates
| and cin/cout were such monumental jokes how can i trust the rest
| of the language? i too have contemplated writing my own language
| but to paraphrase the author, id rather make games than languages
| and C/Python are good enough.
| cyh555 wrote:
| I read this article years ago and haven't been able to find it
| since. It's a pleasant surprise to come across it here.
| smallstepforman wrote:
| Noble quest, but without operator overloading when dealing with
| Matrix*Vector you end up with an unreadable mess for physics,
| skeletal animation etc. There is a reason professional game dev
| is still 90% C++. (Funny enough, amateur gamedev is C# these
| days, students use what they learn at uni).
| nurettin wrote:
| Funny enough, amateur gamedev using C# is a billion USD
| industry.
| krapp wrote:
| ... because that's what ships with Unity.
| andreamonaco wrote:
| I fully agree, in fact I'm writing a game in C too, it's
| https://github.com/andreamonaco/zombieland. Plus I have at least
| another idea for a game project in mind with the same language.
| alexmyczko wrote:
| so do we, one example https://github.com/floooh/pacman.c
| throwaway2037 wrote:
| Before I even read the blog post, my first thought was:
| "Bullshit, this feels like clickbait. Simple DirectMedia Layer
| (SDL2) [one of the most popular gamedev libs for indy games] is
| written in pure C." I guess that the only backdoor to this
| clickbait argument in 2026 can be: "My graphics/audio libary is
| written in pure C, but I use bindings with language X
| (C++/Rust/Zig/etc)."
| Western0 wrote:
| why?
|
| because You know C
___________________________________________________________________
(page generated 2026-02-08 23:01 UTC)