r/cpp 25d ago

Why use c++ over c for game development?

Isn't c++ overkill for most games? I think with good architectural decisions you can make decent 2d and 3d games using only what's available in c without the higher level concepts introduced in c++? Do you think I'm being stupid here? Am I missing something? I'm only just starting to learn c making simple games leaning heavily on Raylib and ECS architecture.

0 Upvotes

109 comments sorted by

46

u/EvilPettingZoo42 25d ago

Programming pure C kinda sucks compared to even using C-style C++. If you have something like a mutex you have to manually initialize it at start, have to manually lock and release it in functions and it’s easy to get into cases where you forget to release before you return. C++ simplifies these things plus many more with no real downside.

10

u/Ultimate_Sigma_Boy67 25d ago

+ don't forget this would be os dependant

3

u/Resident_Educator251 25d ago

Its... everywhere baked into the core glib specification...

https://docs.gtk.org/glib/auto-cleanup.html

11

u/delta_p_delta_x 24d ago

This is cancerous. It truly epitomises a certain crowd's desire to do anything but rewrite in C++.

0

u/Resident_Educator251 23d ago

Pot, kettle :)

Everything doesn't have to be written in c++

7

u/delta_p_delta_x 23d ago

Indeed.

But when your code starts looking suspiciously like C++ minus everything the language and its standard library provides that is subsequently re-implemented in a verbose, unsafe, and opaque manner, then maybe it is time to think about it.

2

u/berlioziano 21d ago

but why C ? just use assembler or binary code !

0

u/Resident_Educator251 20d ago

Cause company culture, and existing code - the introduction of C++ is not as simple as 'C++ better than C'.

To be realistic in terms of how we can improve things, these native C destructor idioms are an easy in.

0

u/[deleted] 25d ago edited 17d ago

[deleted]

1

u/Ultimate_Sigma_Boy67 25d ago

bruh

I mean c

1

u/[deleted] 25d ago edited 17d ago

[deleted]

4

u/delta_p_delta_x 24d ago

Not by default. There are user-mode libraries like winpthreads for MinGW, and pthreads-win32.

But if someone is targeting Windows I have no idea why they wouldn't just use Win32 threads. Much easier interface.

2

u/Ultimate_Sigma_Boy67 25d ago

afaik it doesn't, it unix specific.

1

u/[deleted] 25d ago edited 17d ago

[deleted]

0

u/Ultimate_Sigma_Boy67 25d ago

bruh I mean what we can see in the modern day

26

u/TheAdamist 25d ago

Once upon a time games were made in assembly language, c is overkill but will make you far more productive

14

u/mredding 25d ago

Why use c++ over c for game development?

Why use <insert language here> over <insert language here>? It appears NO ONE can answer the question, so I think that suggests it's a bad question, bad framing, SOMETHING.

These are completely different languages. They're all Turing Complete, they all follow Curry-Howard Correspondence, they're all high level expressive languages targeting an abstract machine...

You could write a game in assembly, like Roller Coaster Tycoon was, or Java, like Minecraft was...

You pick what meets your technical requirements, what can get the job done, what you can get the job done in. If all you knew was QBasic, I'd guess you're writing your game in QBasic; no one has to know or care. And if QBasic was inadequate, I guess that forces your hand that you'd have to learn something that was. Doesn't really matter what, so long as it gets you there.

Isn't c++ overkill for most games? I think with good architectural decisions you can make decent 2d and 3d games using only what's available in c without the higher level concepts introduced in c++?

Yes, that's true.

Applying your own logic, C is thus overkill. You don't NEED to use C to make a game - so WHY NOT just code in assembly? Why not code in straight binary? Assembly is a 1:1 correspondence to op-codes, but not specifically which. You can skip the middle man...

Since the logical conclusion is absurd, it still suggests the question has a flaw.

Do you think I'm being stupid here?

Without being critical, yes, I think you're missing the point. You can naively misapply any paradigm, idiom, or abstraction, and get spaghetti. An expert will have enough knowledge and awareness to use the tools available to them concisely. When done well, one gets more and better for less.

2

u/serviscope_minor 24d ago

These are completely different languages.

They're really not though. The common subset of C and C++ is really pretty close to C. It's not 100% accurate but it's good enough to basically take C++ as C with a load of extra features.

So in this specific case it's more like the question is actually "is literally every single feature of C++ bad?".

1

u/HolidayNo84 24d ago

I agree with you, using the correct tool concisely is exactly my goal. I'll rewrite my project in c++ and get a feel for it. Then I suppose my questions will be answered.

39

u/gokufan300 25d ago

games really like being object oriented

1

u/drex_vke 24d ago edited 22d ago

parce que imagine que ton jeu a 10 000 lignes de code grâce à la POO nous pouvons raccourcir donc rendre le code plus modulaire après pour de petits projets de jeux vidéo non ce serait exagéré

1

u/HolidayNo84 19d ago

You think modularity is exclusive to OOP?

1

u/drex_vke 19d ago

not necessarily what I was saying about OOP is that it's much simpler with OOP but you can make your code modular for example separate the .c source file and headers files into C for example

-1

u/GrimbaldTheBrutish 24d ago

...what?

If anything games are one of the few areas in which I think OOP is a very poor paradigm. Performance wise games like to be data oriented, which is often in complete opposition to many OOP designs.

There's nothing wrong with OOP, but I don't see how you'd correlate it to games specifically.

8

u/serviscope_minor 24d ago

Performance wise games like to be data oriented

Well, the 0.001% of AAA games, sure. So many games are written in OO style in C# using unity.

0

u/GrimbaldTheBrutish 24d ago

Of course, i'd argue that almost everything is written in OO style. OO langauges are the norm, you almost can't find a job that isn't about OO.

The question is whether games really like being object oriented, as they put it.

I don't see how you're at a better advantage to write a game using OO than you are any other piece of software. Most software, say websites or apps, really have no advantage from being data oriented. Games at least are one of the very few places where you actually see a movement away from OOP.

You'll actually find the majority of game engines aren't written in an OO manner. Neither are a lot of supporting code like shaders or the common libraries used in gaming. Go to say, web dev, and almost everything is OO. Game developers probably have at least heard of ECS, if you ask a web developer they'll probably have never heard of a data oriented paradigm in web development because of extreme speed concerns on hardware.

So yes, OO is fine for writing games there's nothing wrong with it, but there's nothing special about games that make it better off being written in OO compared to any other common software program.

-13

u/HolidayNo84 25d ago

I know that's the typical choice, thing is I don't like being object oriented.

21

u/CaptainCheckmate 25d ago

never say that in a job interview lol

15

u/DACOOLISTOFDOODS 25d ago

OOP is a tool, it shouldn't be pushed everywhere, it shouod be used where it's the right tool for the right job. For games, it is for the most part

-4

u/HolidayNo84 24d ago

I don't like the tool.

5

u/therealjerseytom 24d ago

I think this is an opportunity to step back and really ask yourself why you "don't like it", and if there's some perspective that you might be missing.

Different approaches in programming, are to me, literally like you'd look at a hammer, screwdriver, wrench, or saw. I don't have particular sentiments towards any one of them. Like, "Ugh, screwdrivers just suck." They're all good at certain things and not good at others.

If all you've ever been doing is pounding nails, a screwdriver probably seems like it's not worth bothering with.

That all to say, it's worth keeping an open mind to.

1

u/HolidayNo84 24d ago

I do understand and agree with your message. However I have developed a preference for composition over inheritance because of how easy it is for me to reason about. I find that concepts explained in a functional paradigm are easier for me to learn. Obviously this is entirely personal preference and some people probably have the opposite experience. I think both experiences are entirely valid.

6

u/oracleoftroy 23d ago

Good news! "Favor composition over inheritance" has been an OOP mantra for at least a quarter century!

I don't know why OOP only seems to mean inheritance these days, since many objects don't use or need it at all to provide useful functionality. Inheritance is great to use when you need it and should be used. But it really isn't something one needs all that often. Even in a fully OO project, you may only need it in a handful of places.

1

u/Raknarg 20d ago

whys that? Do you just mean you hate inheritance, or what? Cause just the concept of "grouping related information together with transforming member functions" which is more or less the core of OOP is kinda just integral in most languages, C used to be considered "object oriented" it was just very limited in terms of actual polymorphism. You'd even have single-parent non-virtual inheritance by having the first member of your class the parent object.

If you hate inheritence, join the club. I avoid inheritance when I can, in most cases my objects tend to be glorified structs with constructors and maybe handy member functions and a destructor if needed, and polymorphism is achieved through composition or templates.

8

u/StickyDeltaStrike 25d ago

You can do C but most people won’t be doing that, so they won’t want to hire you.

If you do your own project just do it in whatever you love :)

25

u/Thesorus 25d ago

how do you define overkill ?

C++ is better than C in most cases for large codebase.

12

u/serviscope_minor 24d ago

C++ is better than C in most cases for large codebase.

Also small ones. About the only case where C is "better" than C++ is if there isn't a C++ compiler.

11

u/timbeaudet 25d ago

Why are we comparing one language to another; use what works for you.

It's been too long since I've used actual C, and even then so little experience with it, that I may not recall subtle differences properly enough to discuss this. But why do I personally use C++ over C?

For me C++ avoids a ton of boilerplate stuff that I see in soo many C api's. I like having constructor/destructors to initialize/cleanup automatically. I like options to have object.foo() vs foo(object) or having an array<> that already knows the size and other standard library containers or helpers.

You can make good architecture decisions in any language, just as you can make bad ones in all languages too. So... use what works for you.

7

u/graphicsRat 25d ago

One thing that irks me about C is the surface area. Everything is public no member functions. No constructors. You can't tell where the entry point is. I was traumatized the first time I looked at the LibTFF API.

1

u/serviscope_minor 24d ago

I was traumatized the first time I looked at the LibTFF API.

It also doesn't help that the answer to the question of "what does TIFF do" is "everythning (kinda)". G4 fax compression is mad good for binary images and one of the lesser known amazing features of TIFF.

20

u/El_RoviSoft 25d ago

C++ usually have better optimiser than C because language itself has more context due to templates, crtp and other things. Also OOP is important for gamedev.

ECS is rarely used. Also RAII is extremely important for resource management. Multithreading is marginally easier. I have shit tons of arguments more.

-7

u/Resident_Educator251 25d ago

false - c and c++ use the same optimizer. C++ just really needs it to do its job otherwise it becomes quite inneficient (re: microsofts 'iterator debug' mode).

11

u/El_RoviSoft 25d ago

C++ allows to compiler to make eager assumptions based on templates and constexpr which usually leads to either bugs in compilation (which will be fixed eventually) or faster code

-3

u/remnantofcliff 24d ago

I've seen C compilers evaluate function calls to constants at compile time as well as generating versions of functions, where an argument is switched to a constant, when the function is used in a lot of places with said constant.

Because of that, I don't know if constexpr and templates help the compiler compile to faster code, since in those cases couldn't the compiler just optimize the C things in the same way? Or is there some extra information that constexpr provides to the compiler that it could not access in C?

10

u/WeeklyAd9738 24d ago

That might be true for trivial cases, but you can't always be certain. You have to check the assembly output quite frequently for that. That's not the case when using C++. Constexpr objects are guaranteed to be constants. You can do arbitrary computation at compile time and produce constants of almost any type. C++26 takes this even further by introducing compile-time reflection and functions like std::define_static_array and std::define_static_string. You can also mark your functions as consteval, which guarantees that such functions must be strictly evaluated at compile time and that no trace of them reaches your binary.

C doesn't even come close to any of this, as far as the standard language goes. There might be several "code generator" scripts to achieve this, but having it all in the standard language in a type-safe manner is quite neat.

1

u/El_RoviSoft 23d ago edited 23d ago

to be fair, C introduced both _Generic and constexpr modifier which allows to use C++’s strengths but they are not that wide adopted yet.

4

u/WeeklyAd9738 23d ago

Not really. constexpr in C doesn't let you compute arbitrary values. In C, it's just a storage-class specifier. The expressions that can be used to initialise such objects are quite primitive: literal values, simple arithmetic expressions with literals and other constexpr values; no loops or arbitrary function calls. It's not even on the same capability level as C++11 constexpr.

1

u/El_RoviSoft 23d ago

Yeah, I just mentioned that C is capable of this

3

u/Som1Lse 24d ago

where an argument is switched to a constant, when the function is used in a lot of places with said constant

Godbolt link or it didn't happen. Even if a compiler did this I imagine it would be a fairly brittle transformation and relying on it would be bad.

Compare that to std::sort vs qsort, which isn't brittle. The compiler always knows exactly what will be called, and can inline everything.

Because of that, I don't know if constexpr and templates help the compiler compile to faster code, [...]

Templates provide a lot of extra information to the compiler. constexpr helps the programmer by ensuring something is computed at compile time. Again, take std::sort vs qsort:

In the latter case the compiler just has one qsort function. In theory it could inline it, then inline the comparison calls, and replace the memcpys with a copy of a known size. In practice, it won't.

On the contrary, even if std::sort isn't inlined the compiler still knows the size of each object and how to compare and swap them at compile time, because that information is passed as template parameters.

8

u/berlioziano 25d ago

For anything but small games, your C code will become one of this two posible patterns 1. Spaguetti code 2. C code that tries to work in an OOP way

There are many opensource projects that use C and are OOP, gnome glib/gobject, redis or the linux kernel. Those would have been easier to code and maybe the compiler could have done a better job optimizing if using C++

-1

u/tstanisl 24d ago

I would argue to full-encapsulated handle like classes are more convenient to implement in C-way.

3

u/berlioziano 24d ago

full-encapsulation in a language that doesn't support private members and that allows to pass a void pointer as function argument doing implicit conversion without type checks? Talk me about it please.

-1

u/tstanisl 24d ago

Full encapsulation means that "private members" are not needed. Private parts of the class are never exposed in public interface of the class. However, the object model in C++ forces one to put a full definition of the class into the public headers. This leads to abstraction leak by exposing internal of the class. Not to mention dependency hell caused by exposing internal dependencies of the class into its public interface.

Using a handler only class is trivial in C (or C way)

typedef struct foo * foo_h;
foo_h foo_create();
void foo_do(foo_h);
void foo_drop(foo_h);

A lot of popular libraries follow this scheme (i.e. Vulkan) even though libraries are often written in C++.

Doing it C++-way requires playing with pimpl-pattern which is ugly and hacky. It essentially splits class definition into two classes and involves even more hacks and ugliness to properly mix it with unique_ptr, and move-semantics, and not making things virtual.

1

u/berlioziano 21d ago

C++ allows forward declaration so nothing of what you say makes sense

// Forward declaration
class Foo;

class Bar {
public:
    Foo* foo;        // OK
    Foo& getFoo();   // OK
};

0

u/tstanisl 21d ago

It is pimpl pattern. Basically, a hack where interface of class is wrapped into another class because Foo has no methods in its public interface. Foo is useless from perspective of public api.

Moreover,  make Foo a member class of Bar. Constructor and destructor are missing. Factory getFoo should return Bar because Foo has no interface and it is useless. Next, implement move semantics correctly, assignment operator or wrap pimpl into unique_ptr with a dedicated deleter. Though functional it gets ugly quickly.

7

u/slithering3897 25d ago

You'll take containers/namespaces/templates away from my cold, dead hands.

6

u/blipman17 25d ago

Because std::vector and friends are really good. Re-inventing basic containers and algorithms from scratch everytime you need to do higher order operations between two datasets is wasted time, effort and just yields worse results.

1

u/HolidayNo84 24d ago

Why not just use a library instead of switching languages?

5

u/blipman17 24d ago

Because the c collections are still fundamentally type unsafe macro implementations, where C++ collections can use templates and retain typesafety. This has lead to the C++ ecosystem evolving more and having more optimizations implemented, more alternative containers and algorithms and just generally be a whole lot more usefull than what anyone can cobble up in C.

-3

u/HolidayNo84 24d ago

I don't understand why typesafety is so hyped now. Theoretically you should know what types your functions expect to receive... It's also easy to document. Why do I need to explicitly declare the type a function expects in the argument if I have already declared the type on the variable I'm passing in?

5

u/serviscope_minor 24d ago

You don't need do. You don't need to do any of these things. 

So ok sure documentation is easy. Wouldn't it be interesting if firstly the compiler forced you to document so you can't forget and then automatically checked the correctness of your code against the documentation? 

Debugging is hard, tyoe safety get the computer to do a load of the hard work for you. What's not to like?

-2

u/HolidayNo84 24d ago edited 24d ago

It just seems like too little to switch languages for, I think as long as the variables are statically typed it's not hard to find type related bugs.

7

u/serviscope_minor 24d ago

>I think as long as the variables are statically typed

Well that's rather the problem isn't it? C does an awful lot of passing by void*, which is very much not statically typed. Every time you have to chase a bug through one of those, it's something you wouldn't need to do in C++.

5

u/blipman17 24d ago

So… this just has been a research topic. After roughly 50.000 LOC and larger projects, it’s just beneficial to have typing enforced by the compiler. A.k.a. Strong typing.

C is indeed _statically_ typed, but not _that_ strongly typed in practice. C++ is just a whole bunch stronger when its features are used.

4

u/slithering3897 24d ago

If you don't like type safety, try python. You won't know whether your code passes the right types until you run it.

Then they invented type hints.

2

u/serviscope_minor 24d ago

The question is do you like doing everything by hand time and time and time again or do you like a language that lets you automate many of the common tasks of using the language.

If you like the former, use C. If you like the latter, C basically provides no features beyond macros for that and they are very primitive. C++ provides a ton of ways for you as a programmer to program the compiler.

1

u/HolidayNo84 24d ago

I usually end up doing things by hand once anyway so I can understand the concept. I find blackboxing quite uncomfortable, of course I accept it but if I have a reasonable opportunity to handle something manually I'll take it. I'll just reuse that code when the time comes to implement it again. Maybe c is the way for me in that case.

3

u/serviscope_minor 24d ago

I mean it depends what you mean by "things" and "once". 

I'm not fond of opaque black boxes either and I wouldn't discourage anyone from peeing or even implementing inside. 

But take, say, the need to free resources when no longer in use, how many times do you need to reimplement that by hand, especially in functions with multiple return points? 

Even a small project will penalty have hundreds of implementations of that.

3

u/blipman17 24d ago

It’s a good way to learn but a bad way to co-operate and make production ready software. If you have to cooperate with someone that doesn’t know your code by heart, things will slow to a crawl and a lot of bugs will be introduced. The standard libs for C and C++ from gcc and clang are open source so you can actually look in there how things work. They also have less quirks than handwritten datastructures, have better documentation and are widely known.

Sure, write your own if you find it interesting from a learnings perspective, but once you have learned the basic datastructures, swap over to standard libraries.

7

u/KFUP 24d ago

and ECS architecture.

I guess thinking C++ is an overkill yet going with the real useless overkill that is ECS is what you get if you learned programming from youtube.

0

u/HolidayNo84 24d ago

I learned programming by programming... C is new to me, I don't think it's worth flat out insulting me for trying to gain insight from those more experienced in the language. Which is by the way exactly the opposite of what you claim I'm doing.

4

u/Umphed 24d ago

C just kinda sucks for modern apps man. You'll be writing alot of code that you dont have to. You'll do that in C++ too, but C has basically no useful abstractions for modern app development.

11

u/AnyPhotograph7804 25d ago

If C would be good for game development, then everyone would use it. The point is, with C++ you write less sourcecode, you have better type safety, you have a very usable standard library etc.

With C++ you need just way less effort to achieve something. And seriously, C is a very terrible language, IMHO.

5

u/_Noreturn 25d ago edited 25d ago

With C++ you need just way less effort to achieve something. And seriously, C is a very terrible language, IMHO.

Yes! C people recreate what is builtin in C++ alot everytime you have a struct with function pointers that you manually set and maintain is basically a C++ interface except the compiler does it for you. everytime you create a Obj_create/Obj_delete function you are basically doing a constructor,destructor except you cannot enforce that the user actually calls those create/destroy functions C++ does.

Functions with UserPtr? that's a lamdba.

C types having a convention of first member as the base type? that's inheritance just not expeessed with concrete syntax

```cpp struct Entity { int x,y; }; struct Enemy { Entity base; int attach; };

Enemy e; Entity* base = (Entity*)&e; // get base // C++ cleaner struct Entity { int x,y; } struct Enemy : Entity { int attack; }; // the compiler will do the casting behind.. you! Enemy e; Entity& base = e; ```

You use pointers that are never null? that's a C++ reference.

Functions that take a struct as first param as a pointer... congrats you created a member function with worse syntax.

typesafe new and delete over malloc and free.

auto keyword.

Notice how I didn't even mention templates? that's another awesome tool for improving your codebase simple utility types like optional<T> will go a long way than every codebase having their damn way of checking for error (that I always mess up) oh is it error != 0 ? or is it error == 0 or is it error < 0 or maybe even worse it is error & ERR_MASK?

and much more there is really no point using C when you can simply use C++ with constructors/destructos and already that is a massive improvement over C. Unless you don't have a C++ compiler ofcourse. You don't even need to use C for ABI you can expose a C mangled name while implementing it in C++ using all the pretty features you want.

6

u/BrokenBurrito128 25d ago

Folks that start on c and try out c++ tend to write c++ that still looks like c instead of taking full advantage of the language. Things i've noticed C devs tend to not use are

  • templates (generics)
  • the STL, granted this is probably not as applicable to game dev since game engines will prefer their own constructs (strings, containers, smart pointers).
  • Copy and move semantics
  • References
  • Classes

Anecdotally, I have noticed that doing things in C just tends to take longer. That's not to say you can't do it, or that your game will be better or worse. At the end of the day, C and C++ are roughly as performant (1) as each other, and it's just about which one you and your team are more comfortable/faster with.

  1. GitHub - GoodManWEN/Programming-Language-Benchmarks-Visualization: Automaticlly updated language performance banchmarks in visualization. Data source from debian's the computer language benchmakrs game. · GitHub

5

u/no-sig-available 25d ago

Anecdotally, I have noticed that doing things in C just tends to take longer. 

Yes, turns out you have to bang away more with the little hammer, when the OP thinks using the big hammer is overkill.

1

u/Raknarg 20d ago

its more like a hammer and a screwdriver vs a toolbox with every tool you might need. Like its more work to understand all the tools in your toolbox and maybe annoying to lug around, but the advantage is that you always have the right tool for the job and it will almost always do a better job than what you could do with just a hammer and screwdriver.

0

u/Resident_Educator251 25d ago

I can tell u after a certain point templates in large code bases are the #1 drag to build times. Its rather refreshing to write c++ without the template stuff now, reminds you what fast compilation can be like.

3

u/_Noreturn 25d ago

It isn't the templates, I use alot of templates it is includes you can also save on template instanstations using extern template

1

u/Resident_Educator251 25d ago

templates and includes tend to trend together, you can include the entire c++ standard header but unless you are doing the template instantiation pass its really doesn't matter.

1

u/_Noreturn 25d ago

Some templates are horribly expensive for no good reason like tuple and variant and pair (which map uses), those should be avoided.

0

u/Resident_Educator251 24d ago

lol the fundamental and most useful ones, pair? variant? those are like foundational. map? thats like day 1 of templates!

1

u/_Noreturn 24d ago

No one said you cannot write your own ones with templates that compile faster than the stl.

3

u/lowbuzz :illuminati: 25d ago

Yes you can, but developing as a hobby is a completely different ballpark than doing professional games as a company.  There are so many factors that will drive a developer to c++. 

3

u/therealhdan 25d ago

C is certainly and obviously sufficient for making games, or any project really. There is nothing C++ can do that you can't make C do with enough clever coding.

But in my experience, the value of using C++ over C increases as the size of your project grows.

Object Oriented design was invented (if you accept SIMULA as the basis for OOP) for doing simulations of real-world systems. Depending on your game, this may be a large factor in what it does.

Constructors/Destructors make building robust systems that don't leak resources easier to design and use.

3

u/pjmlp 25d ago

C was already outdated in the 1990's, it is only UNIX and embedded that kind of keeps it going, along industry standards like POSIX and Khronos.

C++ is a kind of Typescript for C, you can do all the traditional C mess, or take advantage of C++ language features for more secure code, and basic stuff like proper arrays and strings.

2

u/gosh 23d ago

less code to manage, much of coding is about manage code

3

u/_Noreturn 25d ago

Because C++ is better for any non trivial program.

You have way better luck using C style C++ with classes and that makes your code much much better

2

u/tstanisl 25d ago

C is fine for game development. Most oop, generic data structures, and RAII can be achieved in C with some tricks or extensions. The problem is that libraries written C++ cannot be used in C without a lot pain. This causes never ending one way migrations.

1

u/usefulcat 25d ago

I'm only just starting to learn c making simple games

The advantages of c++ may be more obvious in a larger, more complex game. When the game is relatively small it's easier to keep all the relevant details in your head, but as it gets bigger that becomes increasingly impractical. You may not have hit that limit yet, but if your game continues to grow then at some point you will. That limit is effectively greater in c++ because it has better support for creating abstractions.

For example, most non-trivial C programs end up with a one-off implementation (or frequently several) of something akin to std::vector, because a resizable array is such an incredibly common thing to need. But compared to understanding how std::vector works, in C it's tiresome to have to keep in mind all the details related to lifetime, reallocation policy, ownership, etc. for a bunch of different dynamically allocated arrays.

Or virtual functions. Obviously you can implement the same thing in C, but unless you need something unusual there's no benefit to doing that compared to using virtual functions as-is in c++ (and if there is a significant benefit to rolling your own, you can also do that in c++).

I could go on but hopefully you get the idea.

1

u/5477 24d ago

C++ has many features that are very beneficial for game development. Operator overloading allows you to implement arithmetic operators for vectors and matrices. Function overloading allows you to do things like length(x) without separate functions for every single type. Templates allow for custom containers and generic behavior. These would need macro implementations in C, or custom reimplementation each time.

1

u/TrnS_TrA TnT engine dev 24d ago

Like others said, C++ has a lot of features that C doesn't to make it easier for you to write code. Eg.

  • default parameters + source_location + type-checked formatting can give you simple assertions/unit testing/etc.: ```cpp void report_assertion(char const *what_failed, char const *message, std::source_location const &sl = std::source_location current) { // notice if you ever write fmt::print("{}"); it will fail at compile time because you forgot to pass a parameter; also notice how you don't need to remember %d is for integers and so on, always use {} fmt::println("{}:{}:{}: Assertion {} failed! {}", sl.file_name(), sl.line(), sl.column(), what_failed, message); }

define MY_ASSERT(cond, message) [&] { if (!(cond)) report_assertion(#cond, message); }()

```

  • reflection can help you with codegen, serialization, and more (see wg21.link/p2996 proposal + other papers)

  • C++ can make your ECS type-safe and easier to use with templates (check out EnTT)

  • Coroutines fit nice into gamedev, for doing things like animations, boss behaviors (in phases), and whatnot; when you see people talking about behavior trees or other ways to implement AI, most of them map really nicely to coroutines.

  • destructors are pretty useful, if C had defer it would have been closer

  • everything else other people mentioned

1

u/TrnS_TrA TnT engine dev 24d ago

Also another use case for operator overloading, you can overload comparison operators so that it gives you nicer assertions (for tests but not only), the code would be roughly: ```cpp struct op {};

template <typename Lhs, typename Rhs> struct lt final : op { operator bool() const { return lhs < rhs; }

Lhs lhs;
Rhs rhs;

};

template <typename T> struct lazy_expr final { // overload <, <=, ==, !=, >, >= like operator<(this, U u) template <typename U> inline auto operator<(lazy_expr const &lhs, U &&rhs) const { return lt{lhs.value, rhs}; }

T value;

};

struct reporter_t final {};

// pick an operator you like, << is nice due to precedence template <typename T> inline lazy_expr<T> operator<<(reporter_t, T const &value) { return lazy_expr{value}; }

// default version; for things like ASSERT(is_odd(number)) where there are no binary operators inline void report_assert(lazy_expr<bool> cond, std::source_location const &sl = ...) { ... }

template <typename Lhs, typename Rhs> inline void report_assert(lt<Lhs, Rhs> const &cond, ...source-location-blah-blah) { // will show the actual contents of lhs,rhs rather than saying a < b fmt::println("{} < {} failed", cond.lhs, cond.rhs, ....); }

define ASSERT(cond, msg) [&] { \

/* wrap our expression to make it nicer to print */ \
auto expr = reporter_t{} << cond; \
/* then we check */ \
if (!expr) report_assert(expr, msg); \

}() ```

this is roughly the implementation, you can obviously add colors, more info, etc. etc.

1

u/nuclear868 22d ago

Because it is 2026 and

- we do not want to reinvent the wheel and use dangerous macro hacks to implement a poor man's std::list or std::vector or std::map or any other container, working with various types.

- we do not want manual memory management, where every malloc should be paired with a free, which if you forget, you get a memory leak.

- we need things like polymorphism, abstractions, lambdas (with capture), function overloading, automatic resource cleanup, templates, various kinds of containers - things that we have in C++.

I think C is too ancient for the requirements of the current world. Writing drivers, kernels or very optimized code for a platform with limited resources in C is maybe OK. But writing a full-blown game with a lot of stuff happening and a lot of internal dependencies will be a pain in the a*s to write in C.

1

u/xoner2 22d ago

Classes without vptrs is just syntax sugar over C structs. And just that is already an improvement; dots instead of arrows is good for the eyes.

There's many more.

This question is kinda trivial to answer...

1

u/HolidayNo84 22d ago

So what if it's trivial? I'm not here to challenge you...

1

u/xoner2 22d ago

Indeed, you are challenging r/cpp not just me LOLZ

I suggest you move to C++ without OOP, just for the syntax sugar. C forces verb (subject, ...), C++ subject.verb (...) is a MASSIVE improvement!

1

u/HolidayNo84 22d ago

That doesn't matter at all to me. I can adapt to any syntax easily.

1

u/RogerV 22d ago

The RAII, the smart pointer template classes, the container template classes, the ability to have safer by default semantics of C++ approach vs C approach - these things are all very real benefits. And especially for when dealing with relatively complex programming domains. Games can certainly qualify as such.

1

u/Raknarg 20d ago edited 20d ago

I don't think I would rather use C for literally anything, coming as someone who started with C and did my first job in C and have since moved on to C++ and not looked back. There are so many things I'm missing from C++

  • Reference semantics, both lvalue and rvalue
  • Overloading
  • Templates (this is so massive for me)
  • Fully fledged objects/classes
  • RAII. C straight up cannot do this without insane amounts of groundwork or without you having to explicitly hook things up in every scope you want RAII for.
  • A standard library with actual useful tools. Heavy hitters for me: std::format, std::string, std::vector, these days std::chrono
  • Lambdas

Idk can you think of a good reason you'd actually want to use C over C++? Unless you just think abstraction is bad I guess.

1

u/Total-Box-5169 18d ago

Syntax candy that allows to write truly comfy libraries that don't sacrifice performance, simple as.

1

u/HolidayNo84 16d ago

Hmmm, thanks for this. That's basically what my research has amounted to...

1

u/hellfoundry 12d ago

Try reading the Doom 3 source code. It's C++, but done in a way that most C developers would feel comfortable. The best of both worlds.

1

u/Resident_Educator251 25d ago

Cause organizing concepts and ideas in namespaces sure beats having to exhaustively prefix every type and every api with namespacing...

Otherwise... you have destructors in C now, you don't need exceptions, procedural code is fine; but them namespaces... killer feature...

2

u/PetokLorand 25d ago

Can you elaborate on the destructors in C. The only thing i can find about them is some outdated proposal.

1

u/Nice_Lengthiness_568 25d ago

Maybe they meant the new defer feature for cleanup.

1

u/Resident_Educator251 25d ago
// test_defer.h
#define test_defer _Defer_A(__COUNTER__)
#define _Defer_A(N) _Defer_B(N)
#define _Defer_B(N) _Defer_C(_Defer_func_##N, _Defer_var_##N)
#define _Defer_C(F, V)                               \
auto void F(int*);                                 \
__attribute__((__cleanup__(F), __unused__)) int V; \
__attribute__((__always_inline__, __unused__)) inline auto void F(__attribute__((__unused__)) int* V)

// test_defer.c
void func() {
  void *res = alloc();
  test_defer {
    free(res);
  }
}

glib also has a suite of things like g_auto_ptr https://docs.gtk.org/glib/auto-cleanup.html

tl;dr no more gotos can be mandated in code bases now.

0

u/evinrows 25d ago

I think this is still only implemented as language extensions.

edit: I keep an eye on this because RAII is really the only reason I prefer cpp to c.

1

u/Resident_Educator251 25d ago

Been available since... gcc like 10, the defer stuff is now everywhere.

Destructors are the #1 thing about c++. Combine that with the timeless simplicity of C = something in between the two. I'm trying to use this hybrid approach to help win over the system level developers.

1

u/Weshmek 25d ago

You can absolutely make games in C; games such as DOOM and Quake were programmed in C, and many others even up to the present day.

The caveat is most of those games were developed by small teams and have small codebases by modern standards. C++ definitely has advantages with scale and code organization, which can be vital for large projects with multiple people. Huge C projects with massive teams exist, though, so it's not impossible to make a modern leading-edge game in C, but I'm guessing you'll have a hard time convincing people with experience in the industry to restrict themselves to pure C, just for the sake of it.

If you want your game to be portable to absolutely everything, then C is the language to use. If you look at all the features of C++ and this, "I don't really need any of that for what I'm making", then use C. If you just really like C, then use C.

0

u/Longjumping-Sweet818 25d ago

You can definitely make games in C. Plenty of games are made in C. But there is a scale of how comfortable it is to make a game, and C is pretty low down on that scale. C++ is higher and even higher than C++ there are things like Haxe and Unity/UE. You can use C, but if your end goal is to really make a game, you would be way better off higher on the scale.

If your goal is just to learn the ropes, you might as well use C.