About RAII

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Because constructors can't fail, but resource allocation can. I've always found it much cleaner to use a two-stage init where the constructor sets the object up and an Init() function actually loads the resources. This lets the calling function handle the failure however it wants.

      That having been said, the vast majority of the advice in those guidelines is great.

      -Rez
    • Rereading this, I feel like I should explain a bit further.

      You basically have two possibilities: perform all initialization, including resource acquisition, in constructors, or split the resource stuff into a separate function. Neither way is perfect, but neither way is wrong either. It's a trade-off, like many things in programming.

      The big advantage of doing all loading in the constructor is that you have a perfect bookend. You have matching construction and destruction phases without the need for another function. You also guarantee (theoretically) that any object you construct is ready to go. The idea is that don't have half-built objects laying around. The disadvantage is that constructors can't fail, but initialization can. You can either try to handle it in the constructor, or you need to add some extra data so that the calling function can query the object and make sure it was constructed properly.

      Personally, I think this last point totally defeats one of the biggest advantages of that method. Although the idea is to have an object that's constructed be ready to go, you can't guarantee it, which means that no matter what you do, you will still have partially constructed objects.

      As for separating out initialization, the advantage here is that you can handle resource loading and other such tasks in a function that can return success or failure. You don't have to store any extra state on the object to keep track of whether or not it succeeded, you just return the result from Init() and handle it accordingly. The disadvantage is that you lose symmetry by having this extra function. It also violates the idea that objects should be ready to go when their constructed.

      Personally, I find that the advantages of multi-stage initialization outweigh the disadvantages. That having been said, I will sometimes use the first method for things I expect to never fail (which I enforce with asserts). For example, I have a class that allows me to change aspects of the render state. The constructor stores the current render state and changes it and the destructor restores the render state. This is similar to their example from R.1.

      -Rez
    • Never, ever use C++ exceptions in games for any reason. It's not worth the overhead.

      -Rez
    • Why not? I can catch the exceptions, and depending on their type, i can make the decision to log what went wrong and end the application properly. Or, i can do something about the error and recover from it. If i'm loading a texture and the file was deleted or corrupted, i can replace it with a default texture. Same for models or sounds. I can just log what went wrong and the application would not crash. It is much cleaner than doing:

      Source Code

      1. texture = new Texture()
      2. textureLoaded = texture.load('blah.png')
      3. if (!textureLoaded) {
      4. texture.load('default.png')
      5. }

    • Because they're terrible in C++. Other languages (like Python and I think even C#) are much better at exception handling, but C++ is generally very poor. Check out this post for a more detailed response:
      gamedev.stackexchange.com/ques…s-for-error-handling-in-c

      Make sure you read the posts that the author links to as well. There's a lot more information there.

      At the end of the day it's your game so you can do whatever you want. If you disagree and want to use C++ exception handling, go for it. If you want to write professional-level C++ code, you'll turn off C++ exceptions entirely. I've never worked on a project that used them on the C++ layer for many of the reasons cited in that post.

      -Rez
    • Seconded! Avoid C++ exceptions like the plauge. Another reason to do so is because any studio that you one day work for is most likely not going to use them either, so you would have to get used to a different coding style, and may have to defend your position during an interview if you've used them in a technical test or demo game.
    • Isn't good or bad exception handling more of a compiler issue than a language issue? Also that stack exchange link is several years old and may have expressed a reality that may even have been out of date when it was written. It also links to a "sensible error handling" article that talks about a programmer having to be concerned about not only what he wants to do but also about what errors that happen in the code he wants to call as if it was a bad thing and I don't see why that is.
    • hackwrench wrote:

      Isn't good or bad exception handling more of a compiler issue than a language issue?

      Yes and no. The language sets the rules for exception handling that all compilers must conform to. As long as they follow the spec, they can do it however they want. Exception handling has likely gotten better in more modern compilers but it will never be perfect.


      Also that stack exchange link is several years old and may have expressed a reality that may even have been out of date when it was written.

      The original question was asked two years and last updated three months ago.... not sure how much more recent you want. There has been literally one Visual Studio update since then. I seriously doubt anything has changed to revolutionize exception handling.

      Of course, there's a really easy solution to this: write your own thread and ask the question again. See if anything has changed. I can tell you that it hasn't in the professional world. The last game I worked on (Sims 4) explicitly has "No C++ Exceptions" in the coding guidelines. Anyway, there are people who watch for every little change in C++ across compiler versions who can answer this question better than I.


      It also links to a "sensible error handling" article that talks about a programmer having to be concerned about not only what he wants to do but also about what errors that happen in the code he wants to call as if it was a bad thing and I don't see why that is.

      If you're asking what I think you're asking, it's because if you have to worry about every error the code you're going to call will throw, you have now coupled that code to your calling code through error handling. Say you have function A that calls function B. You set up A to handle all the possible exceptions thrown by B. Everything's fine. How, what happens later on when you have to change B? Now you have to remember to change A as well. What if B is called in 500 different places?

      This isn't really a C++ thing, it's a general exception handling issue. There are ways to handle this of course (trying to always handle exceptions in the functions that generate them, for example), but I think that's the issue the article was talking about. You want to try to avoid this kind of coupling.

      -Rez
    • rezination wrote:

      Of course, there's a really easy solution to this: write your own thread and ask the question again. See if anything has changed. I can tell you that it hasn't in the professional world. The last game I worked on (Sims 4) explicitly has "No C++ Exceptions" in the coding guidelines. Anyway, there are people who watch for every little change in C++ across compiler versions who can answer this question better than I.


      Another thing to bear in mind is that companies often adopt new compiler version VERY slowly. As an example, at work I'm currently using the GCC 4.1.1 compiler, which was released in 2006. There are various reasons why you might be limited from adopting the latest and greatest compilers. Our reason is that we allow customers to build their own plug-ins, so changing compilers means that they will have to rebuild all of their plug-ins to ensure compatibility. Another reason to not use exceptions could be out of anticipation for a future port to another platform, which may require a compiler with less than stellar exception support, requiring a large rewrite. Not to mention general bureaucracy and mistrust over new build tools that is often rife in larger companies.