Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

”...it's mostly a matter of choosing which better C you want.”

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.



This is such a great observation.

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.

[0]: https://docs.racket-lang.org/drracket/languages.html


> It makes me wonder if this can be solved technically by published curated language subsets.

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


The problem with exception-less C++ is that new, delete, ctors, and dtors become timebombs when they fail in a way that would have generated an exception.


I'm not sure why you were downvoted. I almost exclusively write exception-less C++ (compiling everything with "-fno-exceptions"), but correctly handling errors in constructors and destructors is absolutely an important concern. It's not hard to do, obviously, but it does require forethought and heavily encourages delegating complex logic to other parts of the code.


If new fails your program crashing is probably going to be the only outcome anyway, might as well fail from an unhandled exception.

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


dtors that throw come with their own share of problems: If they do so while another exception is in flight (dtors are still called for objects when the stack is being unwound(?)), C++ crashes the process.


For our code base we avoid exceptions, except when due to awkard workarounds, or kludges mostly due to some API that's written in a way that you need to communicate with it with exceptions.

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...


There are a few that people use! Here's a simple one with links to a few others: https://gist.github.com/bkaradzic/2e39896bc7d8c34e042b

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.


Choosing a curated language subset is exactly the "how do I curate the language" problem being referred to. The solution is not to subset a language, but to refuse to superset it. Stop building DSLs and frameworks and domain-specific abstractions and just stick to a flexible core.


>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...”

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.


I was mentoring these kids writing some code in C++ and I saw they were using all this syntax and functionality that was familiar from other languages, but that I had no idea was in C++. You see I used to program on games in C++, but like twenty years ago. I have learned a lot of languages since then, and don't really have a reason to go back to C++ although I liked it fine as a language. But it is possible to write C++ now that is really alien to me.


yep, I choose C89 for this project because there's no Object/Prototype/Class/overloaded bullshit, you get what you wrote and no more, i think it's easier to understand than any other high level language where you have to use obscure things by design.

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 like C, but you definitely don’t “get what you wrote” in any meaningful way. You absolutely have to understand all sorts of nuance about undefined behavior, the size of primitives on various architectures, etc. I’m not advocating for C++, but pointing out that C is far more error prone and surprising than many HLLs. And this doesn’t touch on the regular error prone things about C, like memory management, array indexing, etc.


yep, i said "get what you wrote" and it's true, if you want your iterations to not get out of range you have to do it yourself, if you want to make a dynamic array you have to do it yourself and if something is not working as expected means that you wrote something wrong, that's far from the opaque flexible behaivour on javascript, f.e.

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 :(


Like I said, I wasn't commenting about out-of-range or those other things, I was commenting about the surprising undefined behaviors. :) JavaScript and many other HLLs have their criticisms, but they are generally far less surprising than C. In particular, there are languages like Rust and (to a lesser extent) Go which lack many of the dynamic runtime features of scripting/VM languages and behave very similarly to C, but with far fewer footguns (e.g., no architectures with 9-bit chars!).


Although this was mostly a decompiled project, I really appreciate the architecture and code style of https://github.com/OpenTTD/OpenTTD which seems to use OOP minimally and more c oriented code.




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

Search: