55
\$\begingroup\$

Even though C++ appears to be king, from what I've been told C is still widely used in games, especially on the consoles. However, would writing an entire game engine in C be unreasonable today? What are, if any, some advantages that C has over C++? Why would someone possibly want to use C over C++?

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Console games use c++ FYI! \$\endgroup\$
    – Alan Wolfe
    May 7, 2015 at 14:37
  • \$\begingroup\$ I actually think C would be easier to write games in up to a certain scale, say tens of thousands of LOC or so, mainly because it lets you just focus on bits and bytes without complex data types and builds super fast compared to C++. But after a certain scale (say reaching hundreds of thousands of LOC), I'd start to want to reach for C++ where I'd start actually wanting complex data types, more type safety, possibly exceptions, templates, and going even larger in scale (say millions), for things other than C++ to combine with the C and C++ code. \$\endgroup\$
    – user77245
    Jan 6, 2018 at 22:48
  • \$\begingroup\$ C also has that added advantage of being widely portable even for ABI, so it becomes pretty easy to take your existing C code and then start using it in other languages from, say, an FFI. C++ is a bit more awkward with name mangling, inability to safely throw across module boundaries, vtable reps not being the same across compilers, standard library implementations differing between vendors, etc. Generally I find the C libraries I write lasts longer without needing changes and going out of style, though it takes longer to write anything of scale with it. \$\endgroup\$
    – user77245
    Jan 6, 2018 at 22:55

12 Answers 12

51
\$\begingroup\$

However, would writing an entire game engine in C be unreasonable today?

It's reasonable, but the question is what does it buy you? You likely don't need the extreme portability C offers, and it's a shame to give up all of the features C++ offers unless you're really philosophically set against it.

What are, if any, some advantages that C has over C++?

Better compilation time?

Why would someone possibly want to use C over C++?

I think it's mostly an aesthetic choice. Many people like C because it's simple and minimal and feels clean. C++ has a lot of nice features (namespaces alone make it worth using), but it's also big and messy.

\$\endgroup\$
17
  • 3
    \$\begingroup\$ Until Id Tech 4 \$\endgroup\$
    – optician
    Jul 15, 2010 at 16:40
  • 10
    \$\begingroup\$ @Josh: Easier to debug!? C-programs are notoriously difficult to debug, largely due to pointers and memory management. C++ programs (when using true C++ programming idioms, which tend to avoid pointers and memory-management whenever possible) are several orders of magnitude easier to debug. \$\endgroup\$ Oct 1, 2010 at 18:55
  • 17
    \$\begingroup\$ C can be understood by mere mortals. C++ seems to have lots of features and edge cases seasoned programmers learn about even after a decade of using it every day for living. \$\endgroup\$ Jan 14, 2011 at 13:30
  • 13
    \$\begingroup\$ C++ is a big language, but it's fearsome reputation is spread mostly by people who've just read horror stories and haven't taken the time to learn it. There is a lot to learn, but you get a lot of value in return for that. C++ lets you express lots of things that C simply can't. \$\endgroup\$
    – munificent
    Jan 14, 2011 at 16:13
  • 2
    \$\begingroup\$ @BlueRaja-DannyPflughoeft #define malloc(x) my_malloc(x) #define free(x) my_free(x) and you are now debugging memory. With C++ you never know what will be allocated when, because there are so many ways to allocate memory (new, malloc, class constructors, etc.) \$\endgroup\$
    – yyny
    Apr 21, 2016 at 14:54
61
\$\begingroup\$

I have worked extensively with a pure-C game engine that has shipped several products, so it is absolutely possible. Here's my personal experience with working in both C vs C++ engines:

  1. Using pure-C structures allows you to take advantage of knowledge about the alignment of structures, and you can then use this information to build your object persistence and serialization layers. The engine I worked with had some simple header parsers that would automatically create this metadata about structures, and it made certain types of data operations trivial. Parsing arbitrary C++ header files is essentially impossible, and as soon as you add inheritance and virtual functions you lose the ability to know exactly where things are in memory
  2. Compile time is significantly shorter because you can keep your header files very compact and take advantage of forward declarations of structures.
  3. Debugging can be improved because without the use of templates and inheritance it is very easy to figure out exactly what a certain object is and what it's doing.

All of these benefits could also be achieved just as easily using restrained c++ code that refrains from using templates and inheritance on serialized objects, but it was the CTO's decision that it would be easier to enforce the simplicity if the more confusing elements of C++ were not available.

Personally I think this was slightly extreme, as I really missed the ability to sanely declare variables in for loops and the many completely legitimate uses for inheritance. But, it really didn't cost us much productivity in the end all things considered

\$\endgroup\$
9
  • 6
    \$\begingroup\$ There's really nothing stopping you implementing inheritance in C. And if you use C99 you can declare variables in for loops. \$\endgroup\$
    – jsimmons
    Aug 9, 2010 at 1:05
  • 15
    \$\begingroup\$ Going to disagree with point 3. It's just as easy to write messy, hard-to-debug code in C as it is in C++. Better debugging isn't something inherent in the C language. \$\endgroup\$
    – Dan Olson
    Aug 24, 2010 at 7:02
  • 9
    \$\begingroup\$ Even clean code can be harder to understand in C++ - with overloading, templates, virtual functions, and exceptions, it's much harder to see at a glance exactly what the actual control flow will be. \$\endgroup\$
    – Kylotan
    Aug 24, 2010 at 9:51
  • 7
    \$\begingroup\$ @Dan: Simply by having more stuff, C++ is harder to debug. You can of course restrict yourself from using any of that stuff, in which case it becomes as easy to debug as C - because it becomes C. \$\endgroup\$
    – user744
    Aug 24, 2010 at 16:39
  • 1
    \$\begingroup\$ Less stuff is actually the reason I like C. For example, in C I can just copy bits and bytes around with a memcpy for anything because the type system doesn't allow things like copy ctors and dtors. I can write code knowing I won't have to roll back side effects at almost any given line of code since I can't implicitly exit a function unless I explicitly return out of it; there are no exceptions being thrown. All of this makes writing data structures so much easier -- in C++ just writing a standard-compliant vector is very time-consuming, especially if you want to make it ... \$\endgroup\$
    – user77245
    Jan 6, 2018 at 23:00
21
\$\begingroup\$

I am rewriting a 2D game engine written in C++ and Lua into C and Lua. So far the experience have been quite good. Obviously doing vector and matrix operations don't end up as nice looking in C. But apart from that I have found the experience quite refreshing after spending 10+ years as a C++ developer.

C has a number of advantages over C++:

  1. The compiler will make sure that no code is run at static initialization time. That makes it completely safe to statically allocate global data like strings used as keys e.g.
  2. Transparency. In C assignment or allocating or defining a variable is not going to cause loads of code to run. C++ will auto generate copy constructors for you so you have less control over what gets executed when doing assignment.
  3. A lot of debugging can be easier to due to not getting function names mangled
  4. It is usually okay to use memcpy in C, but it will easy cause trouble in C++, because copy constructors will not be run. Given that memcpy is a lot faster than std::copy that matters.

Apart from that there are a number of advantages to getting into the C way of thinking. In C++ I often find myself making things a bit overgeneralized and abstract. In C I usually cut out things like get-set methods and often preallocate fixed sized arrays rather than use dynamic arrays. Often I end up with shorter and more easily debugged code in C. The data structures are usually flatter and easier to view in a debugger.

To be fair I would never make an app exclusively in C. The reason it works it that I combine it with a higher level language like Lua which can complement C very well, were C is not so strong.

Id software writes most of their engines in C I believe, you can look at Return to castle Wolfenstein which was written in C.

I wrote about some of my experience on scalability of C vs C++ and downsides of STL vector compared to plain arrays.

\$\endgroup\$
3
  • 12
    \$\begingroup\$ FYI, in every instance that I've checked (which is, I think, darwin gcc and vc2008), std::copy will just compile to a call to memcpy if both types are POD. \$\endgroup\$
    – BRaffle
    Aug 23, 2010 at 19:08
  • 3
    \$\begingroup\$ Also, RE: STL vector vs plain arrays, why not use the nice parts of vector and use normal C pointers instead of iterators if you don't like them? You can just do &myvector[N]. It's like the best of both worlds, assuming your C code does memory allocation the same way. Or, in for loops, check out BOOST_FOREACH. Makes it even simpler than C. \$\endgroup\$
    – BRaffle
    Aug 23, 2010 at 19:15
  • 1
    \$\begingroup\$ Thanks for the tip about std::copy memcpy. I didn't know that. When Alexandrescu treated this some years ago it was not the case. About C++ iterators. It is mainly about the philosophy, I try to program how C++ was meant to be program both for the sake of people I work with and to take advantage of C++ features. It was mainly made to point out that some C++ improvements like STL containers are not always better than doing it in the old C way. \$\endgroup\$ Aug 24, 2010 at 8:05
7
\$\begingroup\$

As someone else pointed out, C++ brings the advantage of big shoulders on which you can stand (BOOST, STL etc.). In the end, it is a personal choice, but I would choose C++ because of the available resources. If there are features in C++ that you don't wish to use, then don't use them.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Note that 99% of commercial and in-house game engines steer away from Boost and STL for various reasons (performance guarantee, debugability, thread safeness, control). \$\endgroup\$
    – Kaj
    Jul 31, 2010 at 16:54
  • 44
    \$\begingroup\$ And 99% of statistics are made up. \$\endgroup\$
    – BRaffle
    Aug 23, 2010 at 19:04
  • \$\begingroup\$ I feel like it should be somewhat of a rule to cite all statistics. \$\endgroup\$ Jun 5, 2012 at 22:35
5
\$\begingroup\$

I'll give you a couple more reasons why it would be unreasonable to write a game engine in C instead of C++ today: STL and BOOST.

I can't imagine how it would be worth writing yet another list implementation when you could rely on code that works out of the box (and that you don't have to write!)

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Does any big studio actually use boost? Even STL usage is still under debate, because of portability. At least for console engines. \$\endgroup\$
    – slicedlime
    Jul 16, 2010 at 12:05
  • 2
    \$\begingroup\$ Personally, I'm using Boost.FunctionTypes for c++/lua interaction (see gamedev.net/reference/programming/features/CPPLuaExport/… ) and the Boost random number library for uniform random number generation (for particle systems). Also, Boost.Foreach is neat. BTW, who cares if big studios are not using BOOST? They have the manpower to write their own STL libraries from scratch, I don't. \$\endgroup\$
    – Loris
    Jul 18, 2010 at 15:21
  • 2
    \$\begingroup\$ Yeah but also realise that there's similar libraries for C as well. \$\endgroup\$
    – jsimmons
    Aug 9, 2010 at 1:04
  • 2
    \$\begingroup\$ Lots of people use boost in games, I believe. But it's far from a requirement (or even desirable) for many of us. \$\endgroup\$
    – Dan Olson
    Aug 24, 2010 at 7:03
  • 6
    \$\begingroup\$ People, what you believe is irrelevant: either you know or you don't know. \$\endgroup\$
    – o0'.
    Sep 30, 2010 at 9:54
5
\$\begingroup\$

Writing a game engine in C is reasonable. It's fast and can be ported to multiple systems. For example you could use for Android (with the use of the NDK). You could use it for the iPhone (Objective c is just an extension of c). You could also use it for and of the main OS such as Linux, Mac or Windows. If you feel comfortable with c, I suggest you give it a try!

\$\endgroup\$
3
\$\begingroup\$

I don't think anyone uses C exclusively these days, it's usually mixed together with a higher level language.

Programming in C has some benefits over, say, programming in C++. C++ can do lot of things under the hood that are invisible to the user, which can hurt performance if you're not careful. C++ can also be terrible when it comes to cache usage, which again can hurt your performance.

So it may bring some benefits to write the performance critical parts of a game in a C-like way, rather than in a traditional C++ way. I've never heard of anyone, in recent years, actually writing an entire game in C however.

On some platforms, like the iPhone, using C++ can increase your executable size with a certain chunk of kilobytes (I forgot how much, sorry), which is a reason why some iPhone developers choose to write their code in a mix of C and Objective-C.

\$\endgroup\$
2
\$\begingroup\$

Of course it's reasonable. I personally wouldn't do it, and most of the C fans I know actually just write C-like code in .cpp files. But the languages are similar enough to where it doesn't really matter.

As for why someone would choose to do this, I think it's mostly down to anti-C++ philosophy. Personally I still don't think this is a good reason to choose C over "C-style C++". typedef struct craziness is a good enough reason to steer clear of C, and there are a number of others.

Unfortunately C and C++ are both pretty terrible languages when we get down to it. That's one reason people have been trying to do a lot of their code in script in recent years.

If you're looking for examples of people working in C, you can ignore id as I recall reading that they've abandoned C long ago. Cryptic Studios (Star Trek Online) does all their engine development in C, though. As far as I can tell, yes, it's because of philosophy more than because of any tangible advantage.

\$\endgroup\$
1
\$\begingroup\$

C code is normally valid C++ code.

The main issues with C++ are using it incorrectly (Linus Torvalds hate it for this reason, he also had some other issues with library portability and so on buy he is working at the operating systems level and has to be able to run things on every random chip out there).

For example there's almost no advantage to using a cstyle array[] over a c++ std::vector<> (or similar container).

The vectors are typesafe and can be bounds checked (you can access elements using either get() or [], even if you don't use the array checked method you can still query the size rather than carting it around with the pointer).

But vectors can be slower if, for example, you don't declare the default size in the constructor. Also adding things to a vector can cause slowdowns if it then needs a resize. C++11 adds many advantages too such as uniform initialization (you can now declare and initialize vectors using the same syntax) and there are move constructors that can allow you to avoid copying. You can even make your own custom initializers (if you wanted to do something other than using malloc for some reason).

Or course if you do need to resize things, then vectors are still easier to do it with, you don't have to mess around with malloc, manually copy things and so on.

C++ gives you object orientated code. When compiled it's going to be just as efficient since it's really just an abstraction for humans working with the code. Although things like constructors can slow down object creation. But you will either need the constructor to set the default values or otherwise you can initialize objects without using the constructor (by leaving off the ()'s).

But object orientation makes programming games much easier. Games often deal with objects.

\$\endgroup\$
0
\$\begingroup\$

Yes and no. Yes I have done it a few years back but I needed my game to run in 3D on a unix (not linux) 64 bit remote server with the players on dumb terminals. It was non trivial. C can be nice is you want to integrate LUA but I eventually got lua to work in C++ so I would say yes it is possible but don't do it.

\$\endgroup\$
0
\$\begingroup\$

May a possible good answer be "use both" ?

As I heard that panda3d projects could be optimized, killing bottleneck either using some cython or either recode those parts.

Most of the time, the parts which need to be optimized are the part with a lot of iterations and nesting or with a lot of numeric computing, so my (wild) guess is that one fair compromise would be to use both language, using C for parts that include a lot of low-level programming, so you can't do any misuse of the C++ language for the part which need speed, and C++ for the rest of the game.

Ideally you do the fast part of the engine keeping with the high level in mind, and then use a scripting language or C++ which will use much less nest/loops.

Of course you could never make such an engine that would fit all the games developers would need to do, except if you dedicate your engine for a special kind of game...

But don't take my advice for granted since I'm not an experienced game developer nor an experienced developer... I think C forces you to write fast code, while writing good and fast C++ code for a project as big as a game is a different thing...

\$\endgroup\$
0
\$\begingroup\$

C worked for John Carmack, you might get a lot of advantages by using C, but until you get there to benefit from them it might take you a while.

Here you can find a list of game engines some of them are written in C, maybe you can get some insights on how to do a C game engine by going through their source code.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged .