Monday, September 9, 2013

"An Effective C++11/14 Sampler" Now Online

My talk from last week's Going Native 2013 conference, "An Effective C++11/14 Sampler" is now online. It covers these three guidelines:
  • Understand std::move and std::forward.
  • Declare functions noexcept whenever possible.
  • Make std::threads unjoinable on all paths.
Watch it here and let me know what you think.

Scott

8 comments:

Caibbor said...

Are you guaranteed to get the speed benefits of declaring functions noexcept if you simply compile without exceptions ( with g++ -fno-exceptions ) ?

I won't go into why you would want to do that, but I'll just say that it's done for certain kinds of projects (such as games)

Scott Meyers said...

@Caibbor: Nothing is ever guaranteed, but I'd expect that if you compile without support for exceptions, you'd benefit from the same optimizations you'd get from using noexcept, and in fact I'd expect you'd get additional optimizations, too, because there would be no need to link in exception support from the runtime library. However, if you wanted to handle runtime exceptional conditions in some way (e.g., by returning and testing status codes or by checking errno), that would introduce additional code and additional branches that would make your code bigger and slow things down. Whether you use exceptions or not, there is a cost associated with detecting and dealing with exceptional conditions at runtime.

Caibbor said...

@Scott Meyers: I'm still relatively unopinionated on the subject of using or not using exceptions for game programming, although I currently don't. The basic idea against using exceptions in game programming is that if something goes *exceptionally* wrong during a game, it should just terminate - that there's no reason to catch an exception since a game needs to be completely deterministic; if something doesn't work, your game doesn't work. Stability here isn't a matter like, for example, in accounting software where you need to weasel your way through whatever problem might arise in order to maintain the absolute integrity of data. The only time something can go exceptionally wrong in a game is during load, and once "inside the game" there is very little being done that can go exceptionally, just processing frames, entities interacting, etc. So with that said, there isn't much error checking being done during the most intensive parts of a game's code.

As a counter-example, it is *possible* for something to go "exceptionally wrong" during the game, such as network errors, memory allocation failures from entity spawns, etc.

I haven't found any professional opinion on the matter except for a very brief quote from John Carmack's twitter that he simply doesn't use them - no explanation why. Actually, it was in response to your book:

“Reading More Effective C++. I have grown to appreciate at least some uses of most C++ features, but I still don’t buy in on exceptions.”

This is a subject I’d like to know more about.

Scott Meyers said...

@Caibbor: If your exception-recovery strategy is to shut down and restart with a clean slate, and if your OS or other hosting environment cleans up all your resources for you at process shutdown (e.g., mutexes, file handles, etc.), then there's not much of a case to be made for using exceptions, IMO. I'd expect that for some kinds of games, this would be an acceptable strategy, but for others, it might not be, and certainly for the servers behind online games, I'd be surprised if shutdown-and-restart was acceptable. I suggest you pursue this question with other game developers to see if any consensus has arisen. Let me know what you find out :-)

Bikineev said...

@Scott Meyers: Sorry, I don't fully understand C++11-concept: "Want speed - pass by value". Herb Sutter in gotw4 explained similar example: if you are going to create copied object anyway:

T operator+( T a, const T& b ) {
a += b;
return a;
}
"Did you notice that one parameter is passed by value, and one by reference? That’s because if you’re going to copy from a parameter anyway, it’s often better to pass it by value, which will naturally enable a move operation if the caller passes a temporary object such as in expressions like (val1 * val2) + val3."
But it seems like in your example we could use usual reference to const. Why is passing by value faster in this example? Thank You.

Scott Meyers said...

@Bikineev: My example shows what happens if you pass by value and you also declare that parameter const. If you were to omit the const (which is what you should do, if efficiency is a concern), then the motivation for passing by value (compared to passing by lvalue-ref-to-const) would be that you'd pay for only two moves instead of a copy in cases such as this:

std::string s1, s2;
...
processAndAdd(s1+s2);

As in Herb's example, pass by value is an optimization only when moving is significantly less expensive than copying. Also, pass by value is never as efficient as pass by universal reference, nor is it as efficient as overloading for lvalues and rvalues. That's true for Herb's example, too.

Troy said...

Are you and your publisher any closer to knowing when this book is going to become a reality (in the stores...)?

(Waiting impatiently ... ;))

Scott Meyers said...

@Troy: As I said in my talk, I expect the book to be finished in Q2 2014. I'm hoping to have the entire thing done by the beginning of April. Currently, I have a draft that's about 40% done, but other obligations this fall will prevent me from getting a lot more written until the beginning of next year.