top | item 46927484

(no title)

torlok | 22 days 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.

discuss

order

pron|22 days ago

> 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|22 days ago

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

Yokohiii|22 days ago

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

flohofwoe|21 days ago

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

tialaramex|22 days ago

> 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|22 days ago

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.

Panzerschrek|22 days ago

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

torlok|21 days ago

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

rramadass|21 days ago

Your example is disingenuous. What you are stating is the obvious trivial way of doing something when your objective is actually quite different.

You can get exactly what you are asking for in C++ using techniques of static polymorphism and CRTP pattern (https://en.wikipedia.org/wiki/Curiously_recurring_template_p... and https://en.wikipedia.org/wiki/Barton%E2%80%93Nackman_trick) along with traits and dynamic dispatch (if needed).

For great examples of the above, see the classic Scientific and Engineering C++: An Introduction with Advanced Techniques and Examples by Barton & Nackman (1994).

pjmlp|21 days ago

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.

petters|22 days ago

> 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|22 days ago

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|22 days ago

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|22 days ago

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

direwolf20|22 days ago

Your website seems to be blocking Tor

randomtoast|22 days ago

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|22 days ago

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

uecker|22 days ago

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.

sandpaper26|22 days ago

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

gf000|22 days ago

> but it’s not obviously simpler or safer

On top of likely having worse performance.

direwolf20|22 days ago

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

card_zero|22 days ago

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|22 days ago

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.

vadersb|21 days ago

how is OOP dead if tons of code keep being written using OOP these days? From anything corporate in Java/C# to Hyprland C++

pjmlp|20 days ago

What modern GUI in mainstream OSes isn't using OOP?

Have you bothered to look how GCC and clang are implemented?

feelamee|22 days ago

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|21 days ago

Most operating systems written in C have it all over the place.

Drivers, and extension points for userspace.

lelanthran|21 days ago

> 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|21 days ago

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

pansa2|22 days ago

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|22 days ago

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.

pantalaimon|22 days ago

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

saidinesh5|22 days ago

Linters etc... Validates the subset you're choosing to use for your project too.

krapp|22 days ago

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

wasmperson|22 days ago

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.

etrvic|22 days ago

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|22 days ago

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.

whizzter|22 days ago

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.

HoldOnAMinute|22 days ago

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|22 days ago

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.

patrick451|21 days ago

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.

bobajeff|22 days ago

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

direwolf20|22 days ago

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.

Suppafly|22 days ago

>C is not harder, you just have to implement modern language features by hand

That's definitely harder.

tomcam|22 days ago

> just to feel better about themselves.

Mindread much?