   C++ and doing it right
  Hi again!I'm currently in the process of planning the next iteration of my engine and I decided that I would like to improve the coding style a bit. I've been reading up a lot on C++ best practices and I think I have a much better understanding of C++ as a language now. However, I also looked at the public mod-SDKs of a couple of commercial games and although there's no doubt in my mind that the folks behind Unreal, HL2, Doom 3 and FarCry know what they're doing, the SDKs don't seem to follow a lot of the advice given in most "C++ best practices guides". Here's a couple of things that really struck me:- Nobody's using STL. Everybody writes their own string class, linked list, queue, etc.- Nobody uses namespaces- Everybody uses #define for consts and macros- Nobody uses exceptions, everybody uses return codes- Nobody uses C++ RTTI yet everbody seems to implement their own- Most of these SDKs seem to favor macros over templates- Everybody uses C-style casts- Everybody uses C-headers instead of their C++ equivalents- Nobody uses iostreams, everybody uses some flavor of printf- Everybody uses C++-arrays rather than Vectors- Hardly anybody uses smart pointers- Hardly anybody uses value types extensivelyI can only guess, why this is (portability? legacy c-code? deadlines?) but it's kinda surprising. Anyway, I still want to improve my C++ coding style and was hoping to find some additional advice here. So anything you'd like to share, please do share. And if you can, explain why game developers, even the ones developing middleware engines, still seem to write "C with classes" instead of C++.   
Quote:Original post by Harry Hunt- Nobody's using STL. Everybody writes their own string class, linked list, queue, etc.The STL is not very well supported on consoles, so it isn't frequently used.Quote:Original post by Harry Hunt- Nobody uses namespacesThey bloody well should (this annoys me in UE3).Quote:Original post by Harry Hunt- Everybody uses #define for consts and macrosThey bloody well shouldn't (this also annoys me in UE3, and kills build times and VAX).Quote:Original post by Harry Hunt- Nobody uses exceptions, everybody uses return codes- Nobody uses C++ RTTI yet everbody seems to implement their ownExceptions and RTTI (mostly exceptions) have a fair amount of overhead associated with them and thus are not frequently used. The XBox360 docs also make a point of saying that exceptions are not well supported by the 360 compiler and are best left alone.Quote:Original post by Harry Hunt- Most of these SDKs seem to favor macros over templatesI guess in some cases it could be bad to use templates since you don't want a new function created for each type you use it with, but this still annoys me.Quote:Original post by Harry Hunt- Everybody uses C-style castsAgain, they shouldn't.Quote:Original post by Harry Hunt- Everybody uses C-headers instead of their C++ equivalentsMeh.Quote:Original post by Harry Hunt- Nobody uses iostreams, everybody uses some flavor of printfDoesn't bother me terribly, but I'd prefer streams.Quote:Original post by Harry Hunt- Everybody uses C++-arrays rather than VectorsSee the first point.Quote:Original post by Harry Hunt- Hardly anybody uses smart pointers- Hardly anybody uses value types extensivelyThese are likely unused because of some performance dogma, but it's a shame.If all you're making are indie-level PC games, then it is probably best to ignore what the pros do. There are several decades of legacy code and now-irrelevant coding practices that lots of people still cling to.[Edited by - Driv3MeFar on September 8, 2007 4:04:21 PM];  Excellent reply, thanks!;Quote:Original post by Driv3MeFarQuote:Original post by Harry Hunt- Most of these SDKs seem to favor macros over templatesI guess in some cases it could be bad to use templates since you don't want a new function created for each type you use it with, but this still annoys me. Well, shouldn't there be macros for different types in that case also? Anyway, aliasing and especially pointer aliasing is quite used in embedded world. Like Thin Template Idiom. I'd think using templates creates more possibilities for the compiler to do optimisations.Otherwise I agree -- though I haven't taken a look to any commercial code.;  It doesn't really matter.See, they got the job done. The reason you even mention these products is because they were hyped, and pushed the limits.That's a common problem in software development. Programming practices are means to an end.If a person has a broken leg, you can do the X-ray, surgery, plaster and all that, or you can saw the person's leg off. The patient will survive.Yes, there are better ways to do it (really). But are you going to be the one to make the next Unreal engine, to show that good practices really reduce production costs from $15 million to $13.5?Businesses use what has been proved to work. And not a tiny bit more. And each of those projects is a business venture, designed to earn money. Even if some don't like that, it needs to cover development costs, or the studio goes bankrupt.This is what most of IT is. If anything, companies that emphasize good coding practices are often to be feared, since it inevitably implies ad absurdum enforcement of coding practices, even if it kills the project. There's plenty of overbloated 50-100 million LOC projects that follow every single good coding practices, yet are abandoned and rewritten for a fraction of a cost once they become unmaintainable. Means to an end... nothing more.   ;Quote:Original post by Harry Huntalthough there's no doubt in my mind that the folks behind Unreal, HL2, Doom 3 and FarCry know what they're doingStart doubting. There's no reason to assume that the pro's know everything. They know how to make a game, but they may not know how best to use a language. (Some do, obviously, and some don't)According to an interview, Gabe Newell "had never written a line of multithreaded code" a year or two ago.id has traditionally used C for ages, so I'd expect their engines to be more "C with classes" than actual C++.And of course, most of them have years and years of old legacy code they work on and extend, and which happens to use all sorts of ugly hacks, and again, have more in common with C than C++.As also mentioned, templates and such can be tricky on consoles (lack of compiler support, or just code bloat)But ultimately, I suspect one reason is that game developers as a whole tend to be pretty conservative, and not trust other people's code. "Why use STL's vector? Surely, the one I wrote 4 years ago in C will be faster!".As for languages in general, "won't that be too slow?" No one dares to look at C# because those 5% performance you might lose will surely be unacceptable. And similarly, a lot of people (especially a few years ago) thought C++ was too slow for "real games". C (or, if you were daring, C with classes) was the only suitable language.Just because these people make good games, doesn't necessarily mean they're good at C++ [wink](And of course, as Antheus said while I wrote this, they got the job done, and they know C with classes can get the job done, because it's worked for them so far. Actually teaching the entire team a whole new language (Modern C++) would cost them a lot of resources, and who knows if it'd pay off?)[Edited by - Spoonbender on September 8, 2007 5:43:03 PM];  More great replies, thanks!@Antheus: I'm a pretty pragmatic guy myself and I'm all for "whatever gets the job done". It's just that I realized I had been missing out on a lot, before I learned about modern C++. The language is so much friendlier now ;-)@Spoonbender: I agree that being good at coding games and being good at C++ are two seperate skills. Btw.: From all the SDKs I checked out, the HL2 SDK probably was the worst in terms of coding style. I expected the Doom 3 SDK to be a lot like the GPLed Quake 3 source code (which is all C), but it's actually very nice and class-y.   ;Quote:Original post by Harry HuntBtw.: From all the SDKs I checked out, the HL2 SDK probably was the worst in terms of coding style.I used the HL2 SDK once...*stares off into the distance, a haunted look in his eyes*   ;Quote:Original post by phantomQuote:Original post by Harry HuntBtw.: From all the SDKs I checked out, the HL2 SDK probably was the worst in terms of coding style.I used the HL2 SDK once...*stares off into the distance, a haunted look in his eyes*Same... *shudders*   ;  In addition to what's been mentioned, there's the issue of how well everyone on your team understands the language.  If you're the only one on your team who knows how to use the STL properly, its probably not a good idea to use it in your code because your teammates won't understand what you're doing or how to use the STL properly.C++ supports so many programming styles, that people tend to find one style they like and then use C++ to program in that style.  When they are used to a procedural programming style and see things like functional composition using templates, they run screaming for the door.My advice has always been the same: code the simplest thing it takes to get the job done.  Code something more complex only when you need to, either because of changing requirements ("your clouds suck, they need to look more realistic") or because profiling showed that the simplistic implementation is gobbling up too much CPU.Particularly when it comes to the performance situation, people's intuition is most often wrong and the simpler, clearer code would have been better.  So just code the simpler, clearer code in the first place and only go in and make it more complex if a profile measurement with real data shows that its too slow.   