🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

C or C++

Started by
8 comments, last by GameDev.net 24 years, 8 months ago
Many years ago, C was faster than C++ and that made it more desireable for game programming. However, C++ compilers today are just as fast as C compilers, and in some cases they may even be faster.

A lot of game programming books use C because any C++ compiler should be able to compile C code. Also, there are still people who use C, so this makes for the largest audience.

While I haven't read too many game programming books, I know there are some that use OOP. One example that comes to mind is Real Time Strategy Game Programming in DirectX. While I do *not* recommend this book, the author does use classes (just simple classes, no advanced OOP here). There are other books that use MFC (why?!?!?!?), but I can't name one off the top of my head.
You might want to check out the local B&N and see if you can find a game programming book that uses OOP. Your best bet though would be to take the C code from one of those books and change it to C++. This would help you understand the code better and help you understand OOP better. Good luck!

- Josh

Advertisement
There are a couple of reasons that most game programming books are written using C and not C++. Part of it is due to the fact that most game programming books are several years old, and C++ has only become popular in the last several years. The other is that anyone who knows C++ also knows C, but the reverse is not necessarily true, so the authors are appealing to the least common denominator (I know that that's the reason LaMothe does it). Anyway, there is nothing wrong with using OOP for games; it makes many things easier, and in most cases it's not going to cause a performance loss.

Anyway, as far as books go, LaMothe uses more C++ in Tricks of the Windows Game Programming Gurus, and John de Goes' forthcoming 3D Game Programming With C++ obviously uses C++, but it's probably a little more advanced.

Anyway, even the books written for C are beneficial. Converting any C code to OOP is not that hard, and the principles are independent of the implementation anyway.

I have to say that I find writing game code in C++ more comfortable, but also somewhat annoying. The standard conventions of class based programing such as inheritence, private and public members, and such, give a performance hit. C++ classes are supposed to wrap up functionality into a modular form, with public member functions accessing private member variables. But if you have a member variable such as m_pDDSurface, and you need to get to it, you'd need a function called GetDDSurface() that returns an LPDIRECTDRAWSURFACE. There is so much slow down in these calls that it is easier to just make m_pDDSurface a public variable, and refer to it explicitly as className->m_pDDSurface .. this is great and all, but it really breaks the rules of OOP, as far as I can see. And ultimately your game is going to be faster if you just go and declare a whole bunch of globally used variables as static (mostly DirectX pointers, pointers to blitting structures and such) so you don't have to move them around with C++ objects which pass a pointer-to-this as the first function parameter. I'm not sure which is the best language for game programming, but it sure isn't straight-up C or straight-up C++ .. its a mix, and a mix that needs to be well planned.
Sphet,
You make a good point, but I would like to argue a bit
I used to write classes with a ton of protected member variables, and a have (2?) tons of Get/Set functions, when I hit my head when I slipped in the bathroom and came up with the design for the Flux Capacitor[tm]... No, I mean, when something dawned on me.

The whole point of C++ is encapsulation. Most people start the writing classes by writing a bunch of Get/Set functions. The quesiton that *should* be asked is "why am exposing this memeber? Can't my class do whatever manipulation is necessary instead of exposing this variable?" For example, do you really have to expose the X and Y values of your map to update a viewport, or can the class update it for you?

The key is to come up with a *good* and *not* convoluted abstration. Hide LPDDRAWSURFACE and allow a class to set up direct draw in it's constructor. When the application is shutting down, delete the object and voila'! DirectDraw is magically shut down.

I guess the point I'm trying to say is that Get/Set functions are evil and they really break (IMHO) the whole concept of encapsulation. Naturally there will be some values they you need to return (maybe LPDDRAWSURFACE!) for those use inline fuctions.

Lastly, this is just a style issue, but why do people call their Get/Set functions Get/SetFoo? When Foo could be overloaded to return or set a value depending on it's usage. This has the advantage of making it behave like a variable, like so:
myList.Node (pNode);
pNode2 = myList.Node ();
Anyway, that's my opinion at least.

-OberonZ

Friendly Disclaimer: It is possible that I'm wrong. What do you people think?

---
PAGE FAULT: Please insert "Swap File, Disk 2"
and press any key to continue.
OO is a tradeoff - It trades ease of maintenance (and to a certain extend development) for a lower performance. The key here is that 90% of the game is executed in less that 10% of the code - If these 10% are optimized (and not OO style) the performance loss in the rest of the code is of little importance.

Just MHO

/Niels

(BTW. I use C++, though I hate it - it is one ugly language, not really OO, and not really fast - the perfect combination would be Java and ASM .

<b>/NJ</b>
OberonZ,

Can you, or someone else, explain how inline functions work/look/are faster than others?

Well,

when you declare an inline function Foo(), the compiler will replace Foo with it's code whenever it sees it only it is a performance boost. In other words if it would be faster not to call another function, it copies the content (a' la #define macro) otherwise, it is would be best to leave it as a function call, it does.
At least, that is how VC++6 handles it.

Hope this helps,
-OberonZ

---
PAGE FAULT: Please insert "Swap File, Disk 2"
and press any key to continue.
FYI "Building a 3D Game Engine in C++" by Brian Hook, uses C++. It's an old book though (1995) and deals with a software engine in DOS. It's also an excellent tutorial on 3D graphics in general.
I've looked at a couple of books on game programming and they all seem to use C. Is this simply to appeal to the masses or is C better for games? Does OOP have advantages over procedural programming when it comes to games? If so, can someone suggest a good introductory game programming book utilizing OOP.

Thanks for your replies.

Disclaimer: The following diatribe is unabashedly pro C++ and pro OOP, but I do not attempt to obscure the facts in any way.

Myth #1: Classes are automatically less efficient than their C code equivelents.
Truth 1a: For any function that would have used a C function taking a structure as a parameter to operate on, the C++ member function call will be 100% identical to the C function call in EVERY way. The only rule is that the structure will be the FIRST parameter passed and will be invisible to the coder. (virtual function will be discussed later)
Truth 1b: Simple inline Get/Set function that do not do anything other than the C code they replace (such as node = newNode will ALWAYS be replaced (if this is not turned off in the compiler) and will become identical to the C code, because the assignment or read is just as short as the function call, and if the assignment is itself a function it will obviously be called directly, because it's call(the copy function) will inheirently be more efficient than actually calling a function(the get/set) that then calls it.

Myth #2: There is such a thing as strait C++ that can in someway be worse than strait C (not assuming a conmpiler flaw). C++ includes C, and does not mandate that 1)thou shalt not declare thine variables as global. Nor even 2)thou shalt not access any member variables directly.
Truth 2a: It is perfectly acceptable to use structs in C++, which are simply classes who's members defualt to public instead of private. Also, any struct or class can have as many public, private, or protected members as you want, be they functions or variables.
Truth 2b: C++ even provides means to mix and match use of iostreams and C style io buffers (which I cannot imagine wanting to do unless you are converting a large C program to C++ and must do it in stages).

Myth #3: C++ is/or is not object oriented.
Truth 3a: C++ is a language that can be used with many methodologies including,but not limited to, OOP. It provides direct support for the most common of these: classes, objects, generalization(inheritence),encapsulation(private members and access functions),polymorphism(virtual functions).
Truth 3b: C++ has other distinct advantages over C (although many BUILD upon the OOP groundwork): generic programming support(templates), exception handling support(try,throw,catch), functional programming support(predicates), namespaces, and a VASTLY improved standard library (iostreams, strings, containers, generic algoritms, numeric classes, standard exception classes).

Myth #4: OOP is always better than non-OOP, and OOP must be used all or nothing to gain this benifit.
Truth 4a: I have yet to see a real world C++ program that does not have stand alone functions. Although some OOP "purists" attempt to encaplulate every global piece of data and every control function into a class heirarchy, they are obviously behaving irrationally (unless they need to be able to substitute different applications into a common framework) becuase at some level you have to realize the PROGRAM itself is the root object, and there is no reason not to allow it to have it's own data and function members.

Myth #5: C++ and or OOP features are free.
Truth 5a: I mentioned above that using classes and Get/Set functions can be done with ZERO performance penalty. But that is not the same thing as saying ALL C++ features are free. Virtual functions add size(see below for benifits), RTTI adds size AND reduces speed(but allows things to be done that are otherwise impossible), Templates can be HUGE space wasters (most often when instantiated with various types of pointers), Safe arrays (and string classes) slow down a program but they make it more robust.

Myth #6: C++ can only hope to be as good as efficient as C, never more so.
Truth 6a: Although there is some truth in this, because everything in C++ could be translated to an identical, but convoluted C program, this is like saying nothing can be more efficient than machine language...of course not. This statement though usually implies that standard C++ solutions to a problem are never more effiecient than their standard C counterparts. This is false. Within most areas of programming there are classic tradeoffs, the most notable is size vs. speed. I have often heard that anything that can be done with virtual functions can be done better in C using a switch statement. This is a simple size vs. speed issue: virtual functions spend size (one pointer per object for each vtable it uses, plus one pointer per function but they get constant time access for the function call, the switch implementation spends less size(usually one byte per object) but it has linear time growth (the worst you would EVER implement for anything). In addition to getting the speed advantages of virtual functions, they also allow for client side code to be written only once, even if new types are added late in the project's life. The C version must find EVERY switch statement and change the code.

I just realized how long this post is (and how much longer it would need to be to really explore this issue), so i'm only going to add one more thing.

Get and Set function actually DO serve a purpose (but realize this doesn't mean that their purpose and YOUR purpose are always the same, I often do not write them for simple utility structs), the encapsulation they provide allows you to devise a better method for storing things internally and, as long as you can still convert to the older format, client code will not have to change at all (note the theme...both polymorphism and encapsulation work together to manage change). This was VERY obvious when I worked on a simple 2D physics engine where parts of the code assumed vectors were in terms of DeltaX and DeltaY, but other parts assumed they were in terms of Direction (angle) and Magnitude (distance/force). We easily determined that our code ran faster when stored in Delta(we don't know a name for it) form, but certain algorthms (AND the user interface) wanted everything in the other form. So we wrote a class and provided Get/Set function in both forms, but stored it internally only in the Delta form.

Good Luck.
-Xai (cause I'm sure my name is WAY off the top of your screen

[This message has been edited by Xai (edited October 17, 1999).]

This topic is closed to new replies.

Advertisement