For a beginner that can make things more difficult: in addition to the actual thing you want to learn, you need to first become a capable curator of language features from the past 35 years.
JavaScript today has the same problem: you can’t just start writing a web app because two lines into a tutorial you’ll be barraged with “So this is actually an ES2017b.71 feature that we’re enabling using babel-ts-flooginator, therefore you also need TypeScript and that means you need to...”
C feels clunky today, but writing more code in exchange for not having to curate the language can be helpful for learning.
It makes me wonder if this can be solved technically by published curated language subsets. Racket does this by supporting a bunch of different dialects, specifically to make it easier to teach [0].
One good do something similar for other languages. Step one is probably just writing a doc that says "Here's a standard subset of C++ we call Blah. These are the features it uses and these are the ones it doesn't: ..."
Then you could add tooling so that it will warn you if you use a prohibited feature.
Of course, this just pushes the problem up a level: now a new user has to know which curated sublanguage to use. But that's arguably simpler than doing it on a per-feature basis. At least they can just order a combo instead of having to pick a la carte.
I'm biased, but I generally find the Google C++ Style Guide to be a good curation of C++: https://google.github.io/styleguide/cppguide.html
I generally stick to it in all projects I write. The only exception is that in a few cases I'll use features that are disallowed in Google C++ primarily for historical reasons, most notably exceptions: https://google.github.io/styleguide/cppguide.html#Exceptions
And if you're putting things that can throw exceptions in your ctors or dtors you're probably already writing code that is a timebomb
That to be said, even if you don't use exceptions in C++ - you must write exception safe code - e.g. as much as possible no manual "begin"/"end" but wrap things behind RAII, such that "end" is still called, in case of exception. Hence allocation through unique_ptr, shared_ptr, etc. is preferred over new/delete.
Because you never know the function you are calling whether deep down it won't throw an exception...
And some people choose to use more comprehensive documentation, like Google's C++ style guide, at the cost of imposing more restrictions that are largely in place for corporation-specific reasons that smaller personal codebases don't necessarily need to regard.
That's not a problem with javascript, it's a problem with the development culture, its schizoid relationship with the language and its obsessive need to be "cutting edge." You can, absolutely, just start writing a webapp because vanilla JS and even jQuery still work perfectly well. What you can't as easily do is find tutorials that don't assume Javascript has to be compiled from another language and pushed through a complex tech stack before you can even approach it.
Actually, this tutorial is not just about "building a game engine in C89", it's more about learning the concepts behind game engines, the language and the code is just illustrative examples.
I meant that i think is easier to understand C than other languages cause you see all the flow without weird library stuff, maybe i'm wrong, dunno :(
As i said previously, i'd never do a profesional game proyect (or even a hobby one to be sold) with C89, it takes lots of boilerplate and it feels like reinventing the wheel over and over. I'll have to code a hash map approach, a growing array (already did), a "garbage collector" in C89, things that you either don't need or have in the C++ Stdlib, so yep, you are absolutely right.
Also, i enjoy C :D
Maybe after this i could do the same with C++ macroprogramming
I have no opinion on use of C89 instead of C++, since that's just an implementation detail. Also, for your purposes, it works to your advantage, since C is basically the white-box of C++.
I say this partly in jest, but once I have wrapped all my primitives in structs C has a perfectly reasonable rule for implicit type conversions: "don't".
See https://dlthomas.github.io/using-c-types-talk/slides/slides.... (... which I should really turn into a blog post or something)
That said, can you name a few that work this way? If I've worked on such a platform, it's been a long while.
Part of the problem then is that working with any standard library functions is a huge pain. You have to manually "cast" back and forth all the time.
It's extra important, in writing this kind of C, to pick a granularity of types such that they help you make the distinctions you need without drowning you in casts. And I'm not at all sure such a granularity always exists. It worked out very well on the (greenfield) project I built this way, though.
Can you point to any resources I can use to learn?
Thanks for the suggestion! Seems like a good place to start.
Here are some reasons to choose C: - longevity. The language never changes. C++ does a good job, but not as good as C.
- portability. It runs everywhere.
- readability. Its a simpler language to read and debug.
- size. You can have the whole language memorized, and know how to write it very well.
- prefer C community over the C++.
- avoiding pandoras box. Once you allow one C++ feature, its easy to add another.
But if you yourself want to write your own game with just you or a small team of like-minded people, I would highly encourage using C++. As long as you don't have too many cooks arguing about which C++ features to throw into the pot, you can pick a subset of C++ that isn't much more complex than C (which is already more complex than most realize) and you'll get a much cleaner, safer language. C++ has saner rules for implicit type conversions, namespaces, overloading, and a cleaner notation for dynamic allocation. Those alone make it a sufficiently "better C" to be worth using in my book.
Going farther, even if you don't like "object-oriented programming", I think classes offer modularity and encapsulation features that make them worth using, even if you never once write the keyword "virtual" or use subclassing. (Fun fact: the first version of C++ did not have virtual methods!)
I like C and enjoy programming in it, which I've done for over 20 years. I've written a successful open source project in it and am writing a book that uses C as one of the implementation languages. Even so, I generally only use straight C if I'm writing a library that I want C users to be able to consume. Otherwise, I think C++ contains any number of "better C"'s within it, and it's mostly a matter of choosing which better C you want.