Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
My background is like this: embedded/C, then C++, then higher level OO languages (Java, Scala, Ruby, Groovy, etc.), and now I am doing a small project involving MSP430 microcontroller. Meanwhile, inspired by that, I am contemplating a number of potential pet embedded system projects (meshes and/or RTLS look appealing). So my question is focused primarily on MSP430 for now, though, as an aside, I'd love to have a broader picture, too, involving other microcontrollers.
I was a bit surprised finding out that, after so many years, I might need to go back to C, with its macros, naming conventions, and all. My brain used to be wired for C, but that was many, many years ago.
So what alternatives are available?
C++ feels much more agreeable to me, and, fortunately, seems doable: http://stonepile.fi/object-oriented-approach-to-embedded-programming-with-c/
So if I am to program C++, I just need to inline a lot, avoid virtual functions when possible, and I should be good, right? (at least, memory-wise; they did not benchmark for performance at the above link).
However, if it's so easy, why do people program C? I must be missing something.
The above link also seems to provide a wrapper library for pico]OS. Has anyone used picoOS on MSP430, how reliable is it, and how much resources does it take?
What are the pros and cons of Energia for a simple MS430 project? I tried it, it seems very intuitive and self-documenting, but does it result in as neat a code under the hood? For instance, does Energia initialize unused GPIO to the off state to save energy? Does it initialize unused interrupts? What is the overhead in terms of memory and speed? Etc.
Edit: As a long-time Eclipse person, I'd love to use CCS. I saw that Energia sketches can be imported to CCS. Does it mean that CCS have full support for Energia and can be used as an Energia IDE?
Has anyone used Java Grinder http://hackaday.com/2014/02/10/java-grinder-spits-out-dspic-and-msp430-assembly-code/ ? It seems appealing, but because it spits out an Assembly and not C/C++ code, it's a bit scary to commit to it: what if I am locked into it and it's not ready for the prime time? If it generated C code, I could have easily dropped it if it did not work.
I mentioned Java and my question was deleted, as it's self-evident that other than grinder-like syntactic sugar (not that I mind syntactic sugar!), Java can't run on MSP430. I guess I'll ask another question re WHERE Java can run. This has already grown too long.
What other languages/environments are out there, that fill the niche between low- and hig-level languages?
you seem to have several questions here so I shall go through in the order you numbered them.
Most micros will indeed run C++ (assuming the manufacturer or an open source project provides a compiler back-end), however you have to be wary of a number of drawbacks. C++ Is less deterministic, as in, it provides a significantly higher level of abstraction, which one likely does not want an a resource constrained embedded system, and by and large it is not needed either as embedded systems are rarely powerful enough to usefully run the enormously complex algorithms that warrant a high level language like C++. It is also likely to cause a wide range of hard to track bugs, given the difficulty of debugging code from an embedded system having bugs which are simple and easy to trace are very much nicer. However very importantly, the C++ standard libraries are enormous, they will use excessive ram and very likely waste much of your limited memory space. Thus, even if you do use C++, you wont be able to use any of the techniques that make it powerful.
Simply, I have not used it, however like any RTOS, it is useful if you want a slightly higher level interface, however for a micro the tiny size of the MSP430 it seems overkill, I cannot imagine you doing anything on there that warrants an ROTS, if you need multitasking it would be better to provide simple cooperative tasking yourself.
Unfortunately I have not used that platform either, however given it is based on wiring, my guess it that it does not provide high levels of hardware specific optimization, if you want that I recommend using it for the bulk of your code but make calls into lower level libraries when needed. Beyond that however, it does provide a lovely, self documenting interface, I strongly encourage you to try it. It will also make your code many times easier port if you switch to another micro later (many systems from many companies provide wiring bindings).
You really answer this yourself here, it could be very powerful but is still very immature, I would avoid it purely because of this lock-in until it becomes more mature, then it is worth re-assessing.
Java works nicely on more powerful ARM chips, that is the only place I have seen it in wide use, and implemented fairly efficiently in a micro (ARM provides hardware assistance specifically for Java). Other than this Java is a poor fit for the micro world, at one point it appeared it might go somewhere but this was largely unrealized, for now C likes are the way to go for smaller micros.
Unfortunately there is not really a huge amount of choice other than C. My best recommendation is using higher level libs like wiring. That gives you slightly nicer interfaces without killing efficiency, otherwise there is little point in using a tiny micro if you need high levels of abstraction.
In summary, C does a fairly good job here, I do not think there has been any motivation or effort to make a good replacement. And frankly I largely feel this way too, C never became a bad language, it is still well suited for small systems for the same reasons as it was before. It provides power, efficiency and predictability.
I hope this helps somewhat, if you have any queries please comment me and I will see what I can do to help.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm well educated in the C++ programming language regarding syntax, STL, etc. I haven't done any true projects with it yet other than some college courses. My goal is to start writing progams but attempt to keep it to industry best practices. One of my main goals is to work in the game industry. A door is opening which lead me to ask these questions.
Are C++ game developers usually limited on using all the C++ features? Is it true more or less for each platform?
Is STL used these days in the environment, or should I avoid it?
Do they treat C++ as "everything must be an object" or is it a mix of paradigms?
Any features they tend to not use?
Is C still used, and is it good to show a project completed in it?
I did talk to a famous game designer and he said they don't use STL and said to use basic encapsulation with classes, but he said not to use all other advanced C++ features. The idea is to keep it simple. Is this common?
Thanks in advance!
Bear in mind that "games development" covers everything from phones to websites to PSPs and DS to Wii, Xbox, PS3 and PC/Mac, so the answers you get may vary from one product/developer/platform to another.
1) Yes. Games development can mean that you have to use a particular compiler for your target platform, which may not support some of the "newer" features of C++. You may be restricted on which libraries the development studio will allow you to use. In addition, hardware restrictions on some platforms may influence how you code (e.g. on some systems the cost of virtual functions can be excessively high compared to a PC, so your designs can be restricted away from pure OO for performance reasons. Some systems have limited resources (memory, disk, etc) which will influence your design a lot. On the Playstation3 you may need to write vector-processing SPU tasks rather than traditional single/multithreaded code. etc).
2) Yes. (it's commonly used, as there's usually no point wasting time rolling your own, probably less efficient, equivalents)
3) A mix. Generally in games the key goals are (in rough order): Deliver the impossible on time (why are you going home now, it's only 10pm?), deliver high performance, and try not to crash.
4,6) Generally keep the code simple and flexible so you can develop fast and change to suit the producer's latest vision. You usually have tight deadlines so a lot of design and careful coding tends to be difficult to achieve. The industry unfortunately tends to work on the "churn out the code quickly so we can throw it away and start on the next product", although it is slowly coming around to the idea of re-usable libraries (and more methodical professional practices like unit tests, etc).
A typical scenario is to be asked to code up a quick and dirty demo for the boss, and then when you think you'll be able to throw it away and write it properly, the boss says "we don't have time to rewrite something that already works, start on the next level". So if you're asked to be quick'n'dirty, try not to burn too many bridges or you'll regret it.
5) You may use C, but it depends on the platform and the development house. These days most devlopment will be C++ even if parts of the code are effectively "little more than C" in terms of syntax and features used.
These questions are not at all unique to game development. You will find they vary as much by field as they do by company. I can think of two game design firms that use STL off the top of my head, and also of a few that don't.
1) Define "all C++ features". They typically don't use goto, if that's what you mean.
2) Yes STL is used. You shouldn't avoid it, or not avoid it - use the tools you need to get the job done every time you have a job that needs to get done. Keeping what you use in line with other ways similar problems were tackled -within that project or context- is importent.
3) Depends where you are, both in games and out of games. Some are graduated C guys who want things more C like. Others are C#/Java guys who are more OO (Object Obsessed).
4) goto
5) Yes, and yes. Knowing more than one language is always a good thing. Even if it's just C to C++.
6) Again, use the tools available to solve your problems. Keeping it simple is good when you can, sure.
1) No limitation really, except that you should follow programming guides so as to use them properly (i.e. avoid dinosaurs when using goto's).
2) Yes, its used, and Boost also (which is kinda the preview of the next STL).
3) Mix, always a mix. To say that C++ is only object-oriented is to misunderstand the language. "Everything is an object" is really a Java (or things like it) thing; check out C++'s concept of POD, as an example of how not everything is an object.
4) same as 1)
5) It is used, but as far as I've seen, no new project is being created in C.
6) No... he kinda said the opposite of what I've just said.
Generally, some parts of C++ are limited for patform and performance reasons.
Exceptions and RTTI are normally disabled. Exceptions are expensive when they unwind the stack, and RTTI uses too much memory. Lack of exceptions is particularly a pain because rather than come up with another error handling system, programmers tend to just return NULL. :)
Floats are used almost exclusively over doubles, for performance reasons.
Virtual functions and inheritence can be used, but the virtual table lookup can be costly so sometimes it's optimised out.
The STL can be used, but you normally have to write your own allocators to avoid fragging memory (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html). It's more common to see custom containers - of varying quality. I've never come across boost being used in a console project.
Most code is OO, almost to a fault.
Best C++ programming practices in professional game development environments?
The question is too broad.
Are C++ game developers usually limited on using all the C++ features? Is it true more or less for each platform?
No, or at least extremely unlikely. Depends on platform/compiler.
Is STL used these days in the environment, or should I avoid it?
You shouldn't avoid it, but:
you'll definitely need a profiler if you want stl containers
STL containers are extremely slow in debug builds. This might be a problem, because if you're frequently accessing them, there will be a huge performance drop (say, from 300 fps to 50) in debug build (when compared to release build). Debug code is already slower, and stl containers have large amount of "security check" in debug build.
Do they treat C++ as "everything must be an object"
Every idea is bad if you take it to extremes. "Everything must be an object" is one of those.
Any features they tend to not use?
Why? Unless there is a compiler bug or performance loss there is no point in avoiding feature. Besides, there are commercial 3D games written in java, so I see no point in avoiding feature of compiled language.
Is C still used, and is it good to show a project completed in it?
Some opensource projects may use C, but I can't remember a game completely written in it. There is Q3 engine, but afaik it is mix of C/C++.
I did talk to a famous game designer and he said they don't use STL and said to use basic encapsulation with classes, but he said not to use all other advanced C++ features.
They could decide to avoid stl simply because containers are slow in debug build. It is unclear what exactly you call "advanced C++ features". Also, keep in mind that he is designer, not programmer.
The idea is to keep it simple. Is this common?
The idea may or may not be common, but it is a correct idea for a small teams. With limited human resources everything should be made as simple as possible - to reduce development costs. If you stick to concept like "everything should be an object", decide to build "nice-looking" class hierarchy, etc, AND if you have limited resources, then you are doomed - It is very possible that you'll never finish your project and will be rewriting code forever and trying to decide what should be derived from what. Needless project flexibility and extensibility may kill small project. Game engine doesn't have to be complicated.
Large teams may afford complex solutions, but complexity leads to additional bugs. For example, you could look at sims 3 - it has a VERY advanced system (object "plugins", game resource management, GPU resource management, content "streaming", etc, and I think they even put game logic into a few .NET modules that are stored within game archive...), but extensibility of the system resulted in mountain of bugs after certain updates.
Electronic Arts as one example uses STL, but felt compelled to create their own version of it called EASTL.
Are C++ game developers usually limited on using all the C++ features? Is it true more or less for each platform? These days, I think it's pretty good on the main console platforms but if you were developing for mobile devices I doubt it's quite so even
Is STL used these days in the environment, or should I avoid it? It is used and should be used... but some people don't trust it because in the past STL support was much less even, and sometimes had performance problems
Do they treat C++ as "everything must be an object" or is it a mix of paradigms? Far too general. Varies from person to person and company to company. On average, game developers have a reputation for being less focused on software engineering and more on hacking code, but that's far too generalised to really be of use. However spouting for 30min about design patterns and frameworks and abstractions in an interview is probably not a wonderful plan
Any features they tend to not use? STL still has a bad rep amongst those who worked on older platforms. Exceptions also and RTTI, probably sicne they weren't well supported (and maybe are still not)
Is C still used, and is it good to show a project completed in it? I'm sure it is, and if you have a project then show it, but it's not anywhere near as widely used as C++
I did talk to a famous game designer and he said they don't use STL and said to use basic encapsulation with classes, but he said not to use all other advanced C++ features. The idea is to keep it simple. Is this common?
That view is pretty common but it doesn't mean it's right. You might want to tread carefully to avoid upsetting a 20-year veteran who has not moved with the times
I'm going to assume you're referring to people who develop full-price games for consoles and PC.
"Are C++ game developers usually limited on using all the C++ features?"
I think most are avoiding exceptions, RTTI, and many avoid the STL part of the standard library. They're probably using templates, though not much metaprogramming. I don't think this varies much across platform. But it does vary from company to company.
"Is STL used these days in the environment, or should I avoid it?"
It is used by many, but not all. Don't avoid it - it's a useful tool that is very good at the tasks it is designed for. Just make sure you can get by without it.
"Do they treat C++ as "everything must be an object" or is it a mix of paradigms?"
Different places will work in different ways. There's nothing intrinsic to object orientation in C++ that makes it good or bad for game development. Bear in mind that there is often legacy code or 3rd party libraries that are written in C or designed to be operated from C, so it's very rare that you'll have C++ throughout.
"Any features they tend to not use?"
I think we covered this above.
"Is C still used, and is it good to show a project completed in it?"
Yes, and no. Life is too short to spend on mastering every related language and dialect before you get your first job. Showing the ability to use a C-style library (eg. SDL) should suffice. Obviously if you set your goals on joining a company that just uses C, you will have to consider that.
"I did talk to a famous game designer and he said they don't use STL and said to use basic encapsulation with classes, but he said not to use all other advanced C++ features. The idea is to keep it simple. Is this common?"
See above. Incidentally, game "designers" typically aren't programmers, so watch your terminology. If you apply for a game designer role, you won't usually be showing programming skills.
First a little background ...
In what follows, I use C,C++ and Java for coding (general) algorithms, not gui's and fancy program's with interfaces, but simple command line algorithms and libraries.
I started out learning about programming in Java. I got pretty good with Java and I learned to use the Java containers a lot as they tend to reduce complexity of book keeping while guaranteeing great performance. I intermittently used C++, but I was definitely not as good with it as with Java and it felt cumbersome. I did not know C++ enough to work in it without having to look up every single function and so I quickly reverted back to sticking to Java as much as possible.
I then made a sudden transition into cracking and hacking in assembly language, because I felt I was concentrated too much attention on a much too high level language and I needed more experience with how a CPU interacts with memory and whats really going on with the 1's and 0's. I have to admit this was one of the most educational and fun experiences I've had with computers to date.
For obviously reasons, I could not use assembly language to code on a daily basis, it was mostly reserved for fun diversions. After learning more about the computer through this experience I then realized that C++ is so much closer to the "level of 1's and 0's" than Java was, but I still felt it to be incredibly obtuse, like a swiss army knife with far too many gizmos to do any one task with elegance. I decided to give plain vanilla C a try, and I quickly fell in love. It was a happy medium between simplicity and enough "micromanagent" to not abstract what is really going on. However, I did miss one thing about Java: the containers. In particular, a simple container (like the stl vector) that expands dynamically in size is incredibly useful, but quite a pain to have to implement in C every time. Hence my code currently looks like almost entirely C with containers from C++ thrown in, the only feature I use from C++.
I'd like to know if its consider okay in practice to use just one feature of C++, and ignore the rest in favor of C type code?
The short answer is, "This is not really the most effective way to use C++."
When used correctly, the strong type system, the ability to pass by reference, and idioms like RAII make C++ programs more likely to be correct, readable, and maintainable.
No one can stop you from using the language the way you want to. But you may be limiting yourself by not learning and leveraging actual C++ features.
If you write code that other people will have to read and maintain, they will probably appreciate the use of "real C++" instead of "C with classes" (in the words of a previous commenter).
Seems fine to me. That's the only part of C++ that I really use as well.
Right now, I'm writing a number cruncher. There's no polymorphism, no control delegation, no interaction. <iostream> was a bottleneck so I rewrote I/O in C.
The functions are mostly inside one class which represents a work thread. So that's not so much OO as having thread-local variables.
As well as vector, I use <algorithms> pretty heavily. But the heavy-duty data structures are written in plain C. Mainly circular singly-linked lists, which can't even easily have distinct begin() and end(), meaning not only containers but sequences (and for-loops) are off-limits. And then templates help the preprocessor to generate the main inner loop.
The most natural way of solving your problem is probably right. You don't want solutions in search of a problem. Learning to use C++ is well and good, but object orientation is suited to some problems and not others.
On the other hand, using bsearch from stdlib.h in a C++ program would be wrong.
You should use C++ in whatever way makes the most sense for you.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
In the name of efficiency in game programming, some programmers do not trust several C++ features. One of my friends claims to understand how game industry works, and would come up with the following remarks:
Do not use smart pointers. Nobody in games does.
Exceptions should not be (and is usually not) used in game programming for memory and speed.
How much of these statements are true? C++ features have been designed keeping efficiency in mind. Is that efficiency not sufficient for game programming? For 97% of game programming?
The C-way-of-thinking still seems to have a good grasp on the game development community. Is this true?
I watched another video of a talk on multi-core programming in GDC 2009. His talk was almost exclusively oriented towards Cell Programming, where DMA transfer is needed before processing (simple pointer access won't work with the SPE of Cell). He discouraged the use of polymorphism as the pointer has to be "re-based" for DMA transfer. How sad. It is like going back to the square one. I don't know if there is an elegant solution to program C++ polymorphism on the Cell. The topic of DMA transfer is esoteric and I do not have much background here.
I agree that C++ has also not been very nice to programmers who want a small language to hack with, and not read stacks of books. Templates have also scared the hell out of debugging. Do you agree that C++ is too much feared by the gaming community?
The last game I worked on was Heavenly Sword on the PS3 and that was written in C++, even the cell code. Before that, I did some PS2 games and PC games and they were C++ as well. Non of the projects used smart pointers. Not because of any efficiency issues but because they were generally not needed. Games, especially console games, do not do dynamic memory allocation using the standard memory managers during normal play. If there are dynamic objects (missiles, enemies, etc) then they are usually pre-allocated and re-used as required. Each type of object would have an upper limit on the number of instances the game can cope with. These upper limits would be defined by the amount of processing required (too many and the game slows to a crawl) or the amount of RAM present (too much and you could start frequently paging to disk which would seriously degrade performance).
Games generally don't use exceptions because, well, games shouldn't have bugs and therefore not be capable of generating exceptions. This is especially true of console games where games are tested by the console manufacturer, although recent platforms like 360 and PS3 do appear to have a few games that can crash. To be honest, I've not read anything online about what the actual cost of having exceptions enabled is. If the cost is incurred only when an exception is thrown then there is no reason not to use them in games, but I don't know for sure and it's probably dependant on the compiler used. Generally, game programmers know when problems can occur that would be handled using an exception in a business application (things like IO and initialisation) and handle them without the use of exceptions (it is possible!).
But then, in the global scale, C++ is slowly decreasing as a language for game development. Flash and Java probably have a much bigger slice of market and they do have exceptions and smart pointers (in the form of managed objects).
As for the Cell pointer access, the problems arise when the code is being DMA'd into the Cell at an arbitrary base addresses. In this instance, any pointers in the code need to be 'fixed up' with the new base address, this includes v-tables, and you don't really want to do this for every object you load into the Cell. If the code is always loaded at a fixed address, then there is never a need to fix-up the pointers. You lose a bit of flexibility though as you're limiting where code can be stored. On a PC, the code never moves during execution so pointer fix-up at runtime is never needed.
I really don't think anyone 'distrusts' C++ features - not trusting the compiler is something else entirely and quite often new, esoteric architectures like the Cell tend to get robust C compilers before C++ ones because a C compiler is much easier to make than a C++ one.
Look, most everything you hear anyone say about efficiency in programming is magical thinking and superstition. Smart pointers do have a performance cost; especially if you're doing a lot of fancy pointer manipulations in an inner loop, it could make a difference.
Maybe.
But when people say things like that, it's usually the result of someone who told them long ago that X was true, without anything but intuition behind it. Now, the Cell/polymorphism issue sounds plausible — and I bet it did to the first guy who said it. But I haven't verified it.
You'll hear the very same things said about C++ for operating systems: that it is too slow, that it does things you want to do well, badly.
None the less we built OS/400 (from v3r6 forward) entirely in C++, bare-metal on up, and got a code base that was fast, efficient, and small. It took some work; especially working from bare metal, there are some bootstrapping issues, use of placement new, that kind of thing.
C++ can be a problem just because it's too damn big: I'm rereading Stroustrup's wristbreaker right now, and it's pretty intimidating. But I don't think there's anything inherent that says you can't use C++ in an effective way in game programming.
If you or your friend are really paranoid about performance, then go read the Intel manuals on optimization. Fun.
Otherwise, go for correctness, reliability and maintainability every time. I'd rather have a game that ran a bit slowly than one that crashed. If/when you notice that you have performance issues, PROFILE and then optimize. You will likely find that theres some hotspot piece of code which can possibly be made more efficient by using a more efficient data structure or algorithm. Only bother about these silly little mico-optimization when profiling shows that they're the only way you can get a worthwhile speedup.
So:
Write code to be clear and correct
Profile
PROFILE
Can you use more efficient data structures or algorithms to speed up the bottleneck?
Use micro-optimizations as a last resort and only where profiling showed it would help
PS: A lot of modern C++ compilers provide an exception handling mechanism which adds zero execution overhead UNLESS an exception is thrown. That is, performance is only reduced when an exception is actually thrown. As long as exceptions are only used for exceptional circumstances, then theres no good reason not to use them.
I saw a post on StackOverflow (that I cannot seem to find anymore, so maybe it wasn't posted here) that looked at the relative cost of exceptions vs. error codes. Too often people look at "code with exceptions" vs. "code without error handling", which is not a fair comparison. If you would use exceptions, then by not using them you have to use something else for the same functionality, and that other thing is usually error return codes. They found that even in a simple example with a single level of function calls (so no need to propagate exceptions far up the call stack), exceptions were faster than error codes in cases where the error situation occurred 0.1% - 0.01% of the time or less, while error codes were faster in the opposite situation.
Similar to the above complaint about measuring exceptions vs. no error handling, people do this sort of error in reasoning even more often with regard to virtual functions. And just like you don't use exceptions as a way to return dynamic types from a function (yes, I know, all of your code is exceptional), you don't make functions virtual because you like the way it looks in your syntax highlighter. You make functions virtual because you need a particular type of behavior, and so you can't say that virtualization is slow unless you compare it with something that has the same action, and generally the replacement is either lots of switch statements or lots of code duplication. Those have performance and memory hits as well.
As for the comment that games don't have bugs and other software does, all I can say to that is that I clearly have not played any games made by their software company. I've surfed on the floor of the elite 4 in Pokemon, gotten stuck inside of a mountain in Oblivion, been killed by Gloams that accidentally combine their mana damage with their hp damage instead of doing them separately in Diablo II, and pushed myself through a closed gate with a big rock to fight Goblins with a bird and a slingshot in Twilight Princess. Software has bugs. Using exceptions doesn't make bug-free software buggy.
The standard library's exception mechanisms have two types of exceptions: std::runtime_error and std::logic_error. I could see not wanting to use std::logic_error (I've used it as a temporary thing to help me test, with the goal of removing it eventually, and I've also left it in as a permanent check). std::runtime_error, however, is not a bug. I throw an exception derived from std::runtime_error if the server I am connected to sends me invalid data (rule #1 of secure programming: trust no one, even a server that you think you wrote), such as claiming that they are sending me a message of 12 bytes and then they actually send me 15. In such a situation, there are only two possibilities:
1) I am connected to a malicious server, or
2) My connection to the server is corrupted.
In both of these cases, my response is the same: Disconnect (no matter where I am in the code, because my destructors will clean things up for me), wait a couple of seconds, and try connecting to the server again. I cannot do anything else. I could give absolutely everything an error code (which implies passing everything else by reference, which is a performance hit, and severely clutters code), or I could throw an exception that I catch at a point in my code where I determine which servers to connect to (which will probably be very high up in my code).
Is any of what I mentioned a bug in my code? I don't think so; I think it's accepting that all of the other code I have to interface with is imperfect or malicious, and making sure my code remains performant in the face of such ambiguity.
For smart pointers, again, what is the functionality you are trying to implement? If you need the functionality of smart pointers, then not using smart pointers means rewriting their functionality manually. I think it's pretty obvious why this is a bad idea. However, I rarely use smart pointers in my own code. The only time I really do is if I need to store some polymorphic class in a standard container (say, std::map<BattleIds, Battles> where Battles is some base class that is derived from based on the type of battle), in which case I used a std::unique_ptr. I believe that one time I used a std::unique_ptr in a class to work with some library code. Much of the time that I am using std::unique_ptr, it's to make a non-copyable, non-movable type movable. In many cases where you would use a smart pointer, however, it seems like a better idea to just create the object on the stack and remove the pointer from the equation entirely.
In my personal coding, I haven't really found many situations where the "C" version of the code is faster than the "C++" version. In fact, it's generally the opposite. For instance, consider the many examples of std::sort vs. qsort (a common example used by Bjarne Stroustrup) where std::sort clobbers qsort, or my recent comparison of std::copy vs. memcpy, where std::copy actually has a slight performance advantage.
Too much of the "C++ feature X is too slow" claims seem to be based on comparing it to not having the functionality. The most performant (in terms of speed and memory) and bug-free code is int main() {}, but we write programs to do things. If you need particular functionality, it would be silly not to use the features of the language that give you that functionality. However, you should start by thinking of what you want your program to do, and then find the best way to do it. Obviously you don't want to begin with "I want to write a program that uses feature X of C++", you want to begin with "I want to write a program that does cool thing Z" and maybe you end up at "...and the best way to implement that is feature X".
Lots of people make absolute statements about things, because they don't actually think. They'd rather just apply a rule, making things more tedious, but requiring less design and forethought. I'd rather have a bit of hard thinking now and then when I'm doing something hairy, and abstract away the tedium, but I guess not everyone thinks that way. Sure, smart pointers have a performance cost. So do exceptions. That just means there may be some small portions of your code where you shouldn't use them. But you should profile first and make sure that's actually what the problem is.
Disclaimer: I've never done any game programming.
Regarding the Cell architecture: it has an incoherent cache. Each SPE has its own local store of 256 KB. The SPEs can only access this memory; any other memory, such as the 512 MB of main memory or the local store of another SPE, has to be accessed with DMA. You perform the DMA manually and copy the memory into your local store by explicitly initiating a DMA transfer. This makes synchronization a huge pain.
Alternatively, you actually can access other memory. Main memory and each SPE's local store is mapped to a certain section of the 64-bit virtual address space. If you access data through the right pointers, the DMA happens behind the scenes, and it all looks like one giant shared memory space. The problem? Huge performance hit. Every time you access one of these pointers, the SPE stalls while the DMA occurs. This is slow, and it's not something you want to do in performance-critical code (i.e. a game).
This brings us to Skizz's point about vtables and pointer fixups. If you're blindly copying around vtable pointers between SPEs, you're going to incur a huge performance hit if you don't fix up your pointers, and you're also going to incur a huge performance hit if you do fix up your pointers and download the virtual function code to the SPEs.
I ran across an excellent presentation by Sony called "Pitfalls of Object Oriented Programming". This generation of console hardware has really made a number of people take a second look at the OO aspects of C++ and start asking questions about whether it's really the best way forward.
You can find the presentation here (direct link here). Maybe you'll find the example a bit contrived, but hopefully you'll see that this dislike of highly abstracted object oriented designs isn't always based on myth and superstition.
I have written small games in the past with C++ and use C++ currently for other high performance applications. There is no need to use every single C++ feature throughout the whole code base.
Because C++ is (pretty much, minus a few things) a superset of C, you can write C style code where required, while taking advantage of the extra C++ features where appropriate.
Given a decent compiler, C++ can be just as quick as C because you can write "C" code in C++.
And as always, profile the code. Algorithms and memory management generally have a greater impact on performance than using some C++ feature.
Many games also embed Lua or some other scripting language into the game engine, so obviously maximum performance isn't required for every single line of code.
I have never programmed or used a Cell so that may have further restrictions etc.
C++ is not feared by the gaming community. Having worked on an open-world game engine selling millions, I can say the people in the business are extremely skilled and knowledgable.
The fact that shared_ptr isn't used extensively is partly because there is a real cost to it, but more importantly because ownership isn't very clear. Ownership and resource management is one of the most important and hardest things to get right. Partly because resources are still scarce on console, but also since most difficult bugs tend to be related to unclear resource management (e.g. who and what controls the lifetime of an object). IMHO shared_ptr doesn't help with that the least.
There is an added cost to exception handling, which makes it just not worthwhile. In the final game, no exceptions should be thrown anyway - it's better to just crash than to throw an exception. Plus, it's really hard to ensure exception safety in C++ anyway.
But there are many other parts of C++ that are used extensively in the gaming business. Inside EA, EASTL is an amazing remake of STL that is very adapted for high performance and scarce resources.
There is an old saying about Generals being fully prepared to fight the last war not the next.
Something similar is true about most advice on performance. It usually relates to the software and hardware that was availbale five years ago.
Kevin Frei wrote an interesting document, “How much does Exception Handling cost, really?”.
It really depends on the type of game too. If it's a processor-light game (like an asteroids clone) or pretty much anything in 2d, you can get away with more. Sure, smart pointers cost more than regular pointers, but if some people are writing games in C# then smart pointers are definitely not going to be a problem. And exceptions not being used in games is probably true, but many people misuse exceptions anyways. Exceptions should only be used for exceptional circumstances..not expected errors.
I also heard it before I joined the game industry, but something I've found is that the compilers for specialized game hardware are sometimes... subpar. (I've personally only worked with the major consoles, but I'm sure it's even more true for devices like cell phones and the like.) Obviously this isn't really a huge issue if you're developing for PC, where the compilers are tried, true, and abundant in variety, but if you want to develop a game for the Wii, PS3, or X360, guess how many options you have and how well tested they are versus your Windows/Unix compiler of choice.
This isn't to say that the tools are necessarily awful, of course, but they're only guaranteed to work if your code is simple -- in essence, if you program in C. This doesn't mean that you can't use a class or create a RAII-using smart pointer, but the further from that "guaranteed" functionality you get, the shakier the support for the standard becomes. I've personally written a line of code using some templates that compiled for one platform but not on another -- one of them simply didn't support some fringe case in the C++ standard properly.
Some of it is undoubtedly game programmer folklore, but chances are it came from somewhere: Some old compiler unwound the stack strangely when exceptions were thrown, so we don't use exceptions; A certain platform didn't play with templates well, so we only use them in trivial cases; etc. Unfortunately the problem cases and where they occurred never seem to be written down anywhere (and the cases are frequently esoteric and were a pain to track down when they first occurred), so there's no easy way to verify if it's still an issue or not except to try and hope you don't get hurt as a result. Needless to say, this is easier said than done, so the hesitance continues.
Exception handling is never free, despite some claims to the contrary on here. There is ALWAYS a cost whether it be memory or speed. If it has zero performance cost, there will be a high memory cost. Either way, the method used is totally compiler dependant and, therefore, out of the developers control. Neither method is good for game development since a. the target platform has a finite amount of memory that is often never enough and, therefore, we need total control over, and b. a fixed performance constraint of 30/60Hz. It's OK for a PC app or tool to slow down momentarily whilst something gets processed but this is absolutely untolerable on a console game. There are physics and graphics systems etc. that depend on a consistent framerate, so any C++ "feature" that could potentially disrupt this - and cannot be controlled by the developer - is a good candidate for being dropped. If C++ exception handling was so good, with little or no performance/memory cost, it would be used in every program, there wouldn't even be an option to disable it. The fact is, it may be a neat and tidy way to write reliable PC application code but is surplus to requirement in game development. It bulks out the executable, costs memory and/or performance and is totally unoptimizable. This is fine for PC dev that have huge instruction caches and the like, but game consoles do not have this luxury. And even if they did, the game dev community would almost certainly rather spend the extra cycles/memory on game related resources than waste it on features of C++ that we don't need.
Some of this is gaming folklore, and maybe mantras passed down from game developers who were targeting very limited devices (mobile, e.g.) to gamedevs who weren't.
However, a thing to keep in mind about games is that their performance characteristics are dominated by smooth and predictable frame rates. They're not mission-critical software, but they are "FPS-critical" software. A hiccup in frame rates could cause the player to game over in an action game, e.g. As a result, as much as you might find some healthy level of paranoia in mission-critical software about not failing, you can likewise find something similar in gaming about not stuttering and lagging.
A lot of gamedevs I've talked to also don't even like virtual memory and I've seen them try to apply ways to minimize the probability that a page fault could occur at an inconvenient time. In other fields, people might love virtual memory, but games are "FPS-critical". They don't want any kind of weird hiccup or stutter to occur somewhere during gameplay.
So if we start with exceptions, modern implementations of zero-cost EH allow normal execution paths to execute faster than if they were to perform manual branching on error conditions. But they come at the cost that throwing an exception suddenly becomes a much more expensive, "stop the world" kind of event. That kind of "stop the world" thing can be disastrous to a software seeking the most predictable and smooth frame rates. Of course that's only supposed to be reserved for truly exceptional paths, but a game might prefer to just find reasons not to face exceptional paths since the cost of throwing would be too great in the middle of a game. Graceful recovery is kind of a moot concept if the game has a strong desire to be avoiding facing exceptional paths in the first place.
Games often have this kind of "startup and go" characteristic, where they can potentially do all their file loading and memory allocation and things like that which could fail in advance on loading up the level or starting the game instead of doing things that could fail in the middle of the game. As a result they don't necessarily have that many decentralized code paths that could or should encounter an exception and that also diminishes the benefits of EH since it doesn't become so convenient if there are only a select few areas maximum that might benefit from it.
For similar reasons to EH, gamedevs often dislike garbage collection since it can also have that kind of "stop the world" event which can lead to unpredictable stutters -- the briefest of stutters that might be easy to dismiss in many domains as harmless, but not to gamedevs. As a result they might avoid it outright or seek object pooling just to prevent GC collections from occurring at inopportune times.
Avoiding smart pointers outright seems a bit more extreme to me, but a lot of games can preallocate their memory in advance or they might use an entity-component system where every component type is stored in a random-access sequence which allows them to be indexed. Smart pointers imply heap allocations and things that own memory at the granular level of a single object (at least unless you use a custom allocator and custom delete function object), and most games might find it in their best interest to avoid such granular heap allocations and instead allocate many things at once in a large container or through a memory pool.
There might be a bit of superstition here but I think some of it is at least justifiable.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Recently, I've got a dangerous idea into my head after reading this blog post. That idea can be expressed like this:
I don't need most of what the C++ standard library offers. So, why don't I implement a less general, but easier to use version?
As an example, using the STL spits out reams of incomprehensible and mangled compiler errors. But, I don't care about allocators, iterators and the like. So why don't I take a couple of hours and implement an easy to use linked list class, for example?
What I'd like to know from the StackOverflow community is this: what are the dangers, possible disadvantages and possible advantages to "rolling my own" for most of the existing functionality in C++?
Edit: I feel that people have misunderstood me about this idea. The idea was to understand whether I could implement a very small set of STL functionality that is greatly simplified - more as a project to teach me about data structures and the like. I don't propose re-inventing the entire wheel from the ground up, just the part that I need and want to learn about. I suppose what I wanted to figure out is whether the complexity of using the STL warrants the creation of smaller, simpler version of itself.
Re-using boost or similiar.
Most of what I code is for University and we're not allowed to use external libraries. So it's either the C++ standard library, or my own classes.
Objectivity of this question.
This question is not subjective. Nor should it be community Wiki, since it's not a poll. I want concrete arguments that highlight one advantage or one disadvantage that could possibly occur with my approach. Contrary to popular belief, this is not opinion, but based on experience or good logical arguments.
Format.
Please post only one disadvantage or one advantage per answer. This will allow people to evaluate individual ideas instead of all your ideas at once.
And please...
No religious wars. I'm not a fan boy of any language. I use whatever's applicable. For graphics and data compression (what I'm working on at the moment) that seems to be C++. Please constrain your answers to the question or they will be downvoted.
So, why don't I implement a less
general, but easier to use version?
Because you can't. Because whatever else you might say about C++, it is not a simple language, and if you're not already very good at it, your linked list implementation will be buggy.
Honestly, your choice is simple:
Learn C++, or don't use it. Yes, C++ is commonly used for graphics, but Java has OpenGL libraries too. So does C#, Python and virtually every other language. Or C. You don't have to use C++.
But if you do use it, learn it and use it properly.
If you want immutable strings, create your string as const.
And regardless of its underlying implementation, the STL is remarkably simple to use.
C++ compiler errors can be read, but it takes a bit of practice. But more importantly, they are not exclusive to STL code. You'll encounter them no matter what you do, and which libraries you use. So get used to them. And if you're getting used to them anyway, you might as well use STL too.
Apart from that, a few other disadvantages:
No one else will understand your code. If you ask a question on SO about std::vector, or bidirectional iterators, everyone who's reasonably familiar with c++ can answer. If you ask abut My::CustomLinkedList, no one can help you. Which is unfortunate, because rolling your own also means that there will be more bugs to ask for help about.
You're trying to cure the symptom, rather than the cause. The problem is that you don't understand C++. STL is just a symptom of that. Avoiding STL won't magically make your C++ code work better.
The compiler errors. Yes, they're nasty to read, but they're there. A lot of work in the STL has gone into ensuring that wrong use will trigger compiler errors in most cases. In C++ it's very easy to make code that compiles, but doesn't work. Or seems to work. Or works on my computer, but fails mysteriously elsewhere. Your own linked list would almost certainly move more errors to runtime, where they'd go undetected for a while, and be much harder to track down.
And once again, it will be buggy. Trust me. I've seen damn good C++ programmers write a linked list in C++ only to uncover bug after bug, in obscure border cases. And C++ is all border cases. Will your linked list handle exception safety correctly? Will it guarantee that everything is in a consistent state if creating a new node (and thereby calling the object type's constructor) throws an exception? That it won't leak memory, that all the appropriate destructors will be called? Will it be as type-safe? Will it be as performant? There are a lot of headaches to deal with when writing container classes in C++.
You're missing out on one of the most powerful and flexible libraries in existence, in any language. The STL can do a lot that would be a pain even with Java's giant bloated class library. C++ is hard enough already, no need to throw away the few advantages it offers.
I don't care about allocators,
iterators and the like
Allocators can be safely ignored. You pretty much don't even need to know that they exist. Iterators are brilliant though, and figuring them out would save you a lot of headaches. There are only three concepts you need to understand to use STL effectively:
Containers: You already know about these. vectors, linked lists, maps, sets, queues and so on.
Iterators: Abstractions that let you navigate a container (or subsets of a container, or any other sequence of value, in memory, on disk in the form of streams, or computed on the fly).
Algorithms: Common algorithms that work on any pair of iterators. You have sort, for_each, find, copy and many others.
Yes, the STL is small compared to Java's library, but it packs a surprising amount of power when you combine the above 3 concepts. There's a bit of a learning curve, because it is an unusual library. But if you're going to spend more than a day or two with C++, it's worth learning properly.
And no, I'm not following your answer format, because I thought actually giving you a detailed answer would be more helpful. ;)
Edit:
It'd be tempting to say that an advantage of rolling your own is that you'd learn more of the language, and maybe even why the STL is one of its saving graces.. But I'm not really convinced it's true. It might work, but it can backfire too.
As I said above, it's easy to write C++ code that seems to work. And when it stops working, it's easy to rearrange a few things, like the declaration order of variables, or insert a bit of padding in a class, to make it seemingly work again. What would you learn from that? Would that teach you how to write better C++? Perhaps. But most likely, it'd just teach you that "C++ sucks". Would it teach you how to use the STL? Definitely not.
A more useful approach might be utilizing the awesome power of StackOverflow in learning STL the right way. :)
Disadvantage: no one but you will use it.
Advantage: In the process of implementing it you will learn why the Standard Library is a good thing.
Advantages: eating your own dogfood. You get exactly what you do.
Disadvantages: eating your own dogfood. Numerous people, smarter than 99 % of us, have spent years creating STL.
I suggested you learn why:
using the STL spits out reams of
incomprehensible and mangled compiler
errors
first
Disadvantage: you may spend more time debugging your class library than solving whatever university task you have in front of you.
Advantage: you're likely to learn a lot!
There is something you can do about the cryptic compiler STL error messages. STLFilt will help simplify them. From the STLFilt Website:
STLFilt simplifies and/or reformats
long-winded C++ error and warning
messages, with a focus on STL-related
diagnostics (and for MSVC 6, it fully
eliminates C4786 warnings and their
detritus). The result renders many of
even the most cryptic diagnostics
comprehensible.
Have a look here and, if you are using VisualC, also here.
I think you should do it.
I'm sure I'll get flambayed for this, but you know, every C++ programmer around here has drunk a little too much STL coolaid.
The STL is a great library, but I know from first hand experience that if you roll your own, you can:
1) Make it faster than the STL for your particular use cases.
2) You'll write a library with just the interfaces you need.
3) You'll be able to extend all the standard stuff. (I can't tell you how much I've wished std::string had a split() method)...
Everyone is right when they say that it will be a lot of work. Thats true.
But, you will learn a lot. Even if after you write it, you go back to the STL and never use it again, you'll still have learned a lot.
A bit of my experience : Not that long ago I have implemented my own vector-like class because I needed good control on it.
As I needed genericity I made a templated array.
I also wanted to iterate through it not using operator[] but incrementing a pointer like a would do with C, so I don't compute the address of T[i] at each iteration... I added two methods one to return pointer to the allocated memory and another that returns a pointer to the end.
To iterate through an array of integer I had to write something like this :
for(int * p = array.pData(); p != array.pEnd(); ++p){
cout<<*p<<endl;
}
Then when I start to use vectors of vectors I figure out that when it was possible a could allocate a big bloc of memory instead of calling new many times. At this time I add an allocator to the template class.
Only then I notice that I had wrote a perfectly useless clone of std::vector<>.
At least now I know why I use STL...
Disadvantage : IMHO, reimplimenting tested and proven libraries is a rabit hole which is almost garanteed to be more trouble than it's worth.
Another Disadvantage:
If you want to get a C++ job when you're finished with University, most people who would want to recruit you will expect that you are familiar with the Standard C++ library. Not necessarily intimately familiar to the implementation level but certainly familiar with its usage and idioms. If you reimplement the wheel in form of your own library, you'll miss out on that chance. This is nonwithstanding the fact that you will hopefully learn a lot about library design if you roll your own, which might earn you a couple of extra brownie points depending on where you interview.
Disadvantage:
You're introducing a dependency on your own new library. Even if that's sufficient, and your implementation works fine, you still have a dependency. And that can bite you hard with code maintenance. Everyone else (including yourself, in a year's time, or even a month's) will not be familiar with your unique string behavior, special iterators, and so on. Much effort will be needed just to adapt to the new environment before you could ever start refactoring/extending anything.
If you use something like STL, everyone will know it already, it's well understood and documented, and nobody will have to re-learn your custom throwaway environment.
You may be interested in EASTL, a rewrite of the STL Electronic Arts documented a while back. Their design decisions were mostly driven by the specific desires/needs in multiplatform videogame programming. The abstract in the linked article sums it up nicely.
Advantage
If you look into MFC, you'll find that your suggestion already is used in productive code - and has been so for a long time. None of MFC's collection classes uses the STL.
Why don't you take a look at existing C++ libraries. Back when C++ wasn't quite as mature, people often wrote their own libraries. Have a look at Symbian (pretty horrible though), Qt and WxWidgets (if memory serves me) have basic collections and stuff, and there are probably many others.
My opinion is that the complexity of STL derives from the complexity of the C++ language, and there's little you can do to improve on STL (aside from using a more sensible naming convention). I recommend simply switching to some other language if you can, or just deal with it.
Disadvantage : You're university course is probably laid out like this for a reason. The fact that you are irritated enough by it (sarcasm not intended), may indicate you are not getting the paridigm, and will benefit a lot when you have a paradigm shift.
As an example, using the STL spits out
reams of incomprehensible and mangled
compiler errors
The reason for this is essentially C++ templates. If you use templates (as STL does) you will get reams of incomprehensible error messages. So if you implement your own template based collection classes you will not be in any better spot.
You could make non template based containers and store everything as void pointers or some base class e.g. But you would lose compile time type checks and C++ sucks as a dynamic language. It is not as safe to do this as it would be in e.g. Objective-C, Python or Java. One of the reasons being that C++ does not have a root class for all classes to all introspection on all objects and some basic error handling at runtime. Instead your app would likely crash and burn if you were wrong about the type and you would not be given any clues to what went wrong.
Disadvantage: reimplementing all of that well (that is, at a high level of quality) will certainly take a number of great developers a few years.
what are the dangers, possible disadvantages and possible advantages to "rolling my own" for most of the existing functionality in C++?
Can you afford and possibly justify the amount of effort/time/money spent behind reinventing the wheel?
Re-using boost or similiar.
Rather strange that you cannot use Boost. IIRC, chunks of contribution come in from people related to/working in universities (think Jakko Jarvi). The upsides of using Boost are far too many to list here.
On not 'reinventing the wheel'
Disadvantage: While you learn a lot, you also set yourself back, when you come to think of what your real project objectives are.
Advantage: Maintenance is easier for the folks who are going to inherit this.
STL is very complex because it needs to be for a general purpose library.
Reasons why STL is the way it is:
Based on interators so standard algorithms only need a single implementation for different types of containers.
Designed to behave properly in the face of Exceptions.
Designed to be 'thread' safe in multi threaded applications.
In a lot of applications however you really have enough with the following:
string class
hash table for O(1) lookups
vector/array with sort / and binary search for sorted collections
If you know that:
Your classes do not throw exceptions on construction or assignment.
Your code is single threaded.
You will not use the more complex STL algorithms.
Then you can probably write your own faster code that uses less memory and produces simpler compile/runtime errors.
Some examples for faster/easier without the STL:
Copy-on-Write string with reference counted string buffer. (Do not do this in a multi-threaded environment since you would need to lock on the reference count access.)
Use a good hash table instead of the std::set and std::map.
'Java' style iterators that can be passed around as a single object
Iterator type that does not need to know the type of the container (For better compile time decoupling of code)
A string class with more utility functions
Configurable bounds checking in your vector containers. (So not [] or .at but the same method with a compile or runtime flag for going from 'safe' to 'fast' mode)
Containers designed to work with pointers to objects that will delete their content.
It looks like you updated the question so now there are really two questions:
What should I do if I think the std:: library is too complex for my needs?
Design your own classes that internally use relevant std:: library features to do the "heavy lifting" for you. That way you have less to get wrong, and you still get to invent your own coding interface.
What should I do if I want to learn how data structures work?
Design your own set of data structure classes from the ground up. Then try to figure out why the standard ones are better.