Remix.run Logo
torlok 3 hours ago

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.

pron 3 hours ago | parent | next [-]

> 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 2 hours ago | parent [-]

> 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 2 hours ago | parent [-]

There are linters to do that enforcement automatically.

petters 3 hours ago | parent | prev | next [-]

> 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 3 hours ago | parent | next [-]

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

levodelellis 2 hours ago | parent | prev [-]

In fact, I don't believe you so much that I'm willing to say you're full of shit. No compiler capable of both C++ and C will be twice as fast renaming the file to C

jsheard 2 hours ago | parent [-]

I agree it shouldn't really matter if there's no C++ features in play, but I suppose third party headers could bite you if they use #ifdef __cplusplus to guard optional C++ extensions on top of their basic C interface. In that case the compiler could be dealing with dramatically more complex code when you build in C++ mode.

uecker an hour ago | parent [-]

Maybe it is similar for the same compiler (but one should check, I suspect C could still be faster), but then there are much more C compilers. For example, TCC is a lot faster than GCC.

levodelellis 38 minutes ago | parent [-]

tcc is 8x faster, twice as fast isn't doing it justice.

As for the header thing, that'd could potentially be true if the compile time was something like 450ms -> 220ms, but why bother saying it when you're only saving a few hundred milliseconds

levodelellis 3 hours ago | parent | prev | next [-]

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.

rustyhancock an hour ago | parent | next [-]

Another option can be if you have a core set of headers your project will use (and is stable) just precompiling them.

direwolf20 2 hours ago | parent | prev [-]

Your website seems to be blocking Tor

wasmperson an hour ago | parent | prev | next [-]

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.

pansa2 3 hours ago | parent | prev | next [-]

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 3 hours ago | parent | next [-]

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.

WalterBright 2 hours ago | parent | next [-]

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 22 minutes ago | parent [-]

Just want to off-topic-nerd-out for a second and thank you for Empire.

teo_zero 2 hours ago | parent | prev [-]

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.

ninkendo an hour ago | parent | next [-]

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.

uecker 2 hours ago | parent | prev [-]

why not std::string?

teo_zero an hour ago | parent | next [-]

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.

direwolf20 2 hours ago | parent | prev [-]

It's a class, so it doesn't work in C.

uecker an hour ago | parent [-]

Sure, but you can have a similar string abstraction in C. What would you miss? The overloaded operators?

pantalaimon 2 hours ago | parent | prev [-]

C is not a subset of C++, there are some subtle things you can do in C that are not valid C++

uecker 2 hours ago | parent [-]

Some subtle and some not so subtle.

etrvic 3 hours ago | parent | prev | next [-]

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 3 hours ago | parent [-]

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.

randomtoast 3 hours ago | parent | prev | next [-]

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.

mjburgess 3 hours ago | parent | next [-]

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 3 hours ago | parent [-]

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

sandpaper26 3 hours ago | parent | prev | next [-]

This reads like an LLM generated response that simply restates the comment it's replying to

randomtoast 3 hours ago | parent [-]

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.

uecker 2 hours ago | parent | prev | next [-]

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 an hour ago | parent [-]

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 an hour ago | parent [-]

Yes, but this is more a theoretical problems while references are common in C++.

direwolf20 3 hours ago | parent | prev | next [-]

It's important that you do these things yourself before you utilise the compiler to do them for you, so you have real understanding.

gf000 3 hours ago | parent | prev | next [-]

> but it’s not obviously simpler or safer

On top of likely having worse performance.

3 hours ago | parent | prev [-]
[deleted]
whizzter 3 hours ago | parent | prev | next [-]

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.

bobajeff 2 hours ago | parent | prev | next [-]

I remember the creator of Kaiju engine stating something about C++ compilers producing slower code with C-style C++.

HoldOnAMinute 3 hours ago | parent | prev | next [-]

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 2 hours ago | parent [-]

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.

tomcam 3 hours ago | parent | prev | next [-]

> just to feel better about themselves.

Mindread much?

krapp 3 hours ago | parent | prev [-]

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