November 2007

Unguaranteed Order of Pre-main Object Initialization in C++ - Any Solutions?

The C++ standard leaves the relative initialization order of global and static data undefined. The only thing that the compilers must guarantee is that all such data have been initialized before the invocation of main(). In any large and well-designed project, there are no or very few global objects. But static member data in classes are unavoidable in many occasions.
The unspecified and unguaranteed relative order of initialization of these objects can lead to undesirable effects. You could very well end up using objects that have not been initialized yet.
This is my problem. I’m in the design stage of a large library, and I want to know any thoughts or useful material you might have or have seen relevant to this problem. (This library is a game engine, by the way, and we will be delighted to have anyone with enthusiasm and technical expertise on board with us.)
One solution that comes to mind is doing all the initialization of static object in functions (for example, one per each class with static data members) and “registering” these functions and their relative priority at the static initialization time (before main()) but do not invoke them then. The only static object that is actually initialized pre-main is the object that we register these initialization functions to. At the beginning of main(), the said registrar object goes through its list of init functions, sorted by relative priority, and invokes them one by one. The static objects can register termination functions as well to be invoked at the termination of main. This way, the relative order is ensured and the initialization and termination are done pre-main (actually, only before all the objects initialized in main(), but after the start of main() itself,) and post-main, respectively.
The problems with this scheme are the verbosity of writing initialization/termination functions, and the fact that the static objects are constructed before main() anyway. We only re-initialize them. This can be costly, wrong or plain impossible, depending on the design of each specific class.
Has anyone got a better way? Any illumination?

C++
programming

Comments (1)

Permalink

The Films I Recommend

I do get asked sometimes to recommend movies to people. That’s a really hard thing to do. Of course, I can recommend many films off the top of my head, but would they like them is entirely another matter. This list here is in the former spirit. I’ve considered several factors in recommending these specific movies for. I have all of them in my own collection. I like all of them very much myself. Many are quite unusual and not mainstream. Most of them are newer films (past decade or so) and they amount to a very round and straightforward number. Here are the 64 movies I believe everyone should see at least three times:

  1. 2046
  2. Abre Los Ojos
  3. American Psycho
  4. Avalon
  5. Battle Royale
  6. Blade Runner
  7. Brazil
  8. Crash
  9. Dark City
  10. Dekalog
  11. Dogma
  12. Donnie Darko
  13. Elizabethtown
  14. Equilibrium
  15. Eternal Sunshine of the Spotless Mind
  16. Fight Club
  17. Gattaca
  18. Godfather, The
  19. Great Expectations
  20. Heat
  21. Hero (Ying Xiong)
  22. History Boys, The
  23. Inconvenient Truth, An
  24. Interview with a Vampire
  25. Kingdom of Heaven
  26. Kiss Kiss, Bang Bang
  27. Machinist, The
  28. Man on Fire
  29. Matrix, The
  30. Memento
  31. Monty Python and the Holy Grail
  32. Nineteen Eighty-Four
  33. Notting Hill
  34. Oldboy
  35. Pan’s Labyrinth
  36. Pay it forward
  37. Pitch Black
  38. Pulp Fiction
  39. Rashomon
  40. Requiem for a Dream
  41. Reservoir Dogs
  42. Revolver
  43. Ronin
  44. Scent of a Woman
  45. SE7EN
  46. Seven Samurai, The
  47. Serendipity
  48. Serenity
  49. Sin City
  50. Soylent Green
  51. Spartan
  52. Spirited Away
  53. Star Wars
  54. Strings
  55. Sympathy for Lady Vengeance
  56. Sympathy for Mr. Vengeance
  57. Thank You For Smoking
  58. THX 1138
  59. To Kill A Mocking Bird
  60. Trois Couleurs
  61. Twelve Monkeys
  62. Unforgiven
  63. Usual Suspects, The
  64. V for Vendetta

I would be delighted to read your comments on these movies, and any recommendations you might have. Please share with me and the rest of the people (the 2 or 3 other people!) that might see this post and your comments.

entertainment
movie-list

Comments (8)

Permalink

I Will Once More Walk with the Gods

(That’s at least once more!)
The other night, I played through the demo release of God of War: Chains of Olympus and on a PSP, no less! The demo was extremely short (5-10 minutes of gameplay) but it was mighty fun! Kratos is still slashing his way through objects, people and beasts and tearing them apart. Even the controls felt good (aside from rolling, which has become too hard to do.) He had one new move and the single magic he received by killing the big, fat, stupid, ugly, bearded, one-eyed and vile Persian King (what else did you expect? it’s a cliché now! :-( ) is new, but the game play is the same as the classic, which can be a Good Thing or a Bad Thing, depending on the story and whether it has just the right amount of sugar to set it apart yet remain in the same godly series (the thing the GoW2 did beautifully.)

Here, help yourself to a line or two from GoW2. If you have been lucky enough to play through it, well…. Yaaaay! If not, go get your hands on a PS2 if you’ve ever even remotely liked any 3D computer game, because you’ll love these two!

Prometheus: God of War! You… live!
Kratos: I no longer walk with the Gods. Who has placed you in this torment?
Prometheus: Zeus!…

(You can read the whole script of GoW2 here if you’re interested.)

entertainment

Comments (0)

Permalink

C++: Fun With Precompiled Headers

Those of you who have worked on middle-sized to large projects in C++ (any more than 50000 lines of code) know that build time becomes a rather important factor in the development process. On any typical project, a full build time can very well exceed 10 minutes on a modern machine. Although there are many factors aside from mere line count (for example, heavy use of templates) affecting the exact build time, any amount of time more than a few seconds you spend staring at your monitor waiting for a build to finish is hardly pleasant.

On really large projects, some very drastic measures are taken to mitigate the problem of build times. These may include distributed (even grid-based) build systems or dedicated build machines that automatically build the project after each code update to the project repository or at designated intervals. But for any smallish company or team, such measures may not be applicable. Using Pre-Compiled Headers (or PCH for short) can be an attractive solution.

First let me go over some basic stuff. As you know, a C++ compiler only accepts individual C++ code files as input (called a compiland (like operand!) sometimes.) Your project might easily have a couple of hundred (to a few thousand) source files (not counting the header files) but each must be fed through the compiler to produce an object file individually. The next step would be to run a linker (or alternately a “librarian”) to link those object files together and produce an executable (or a library) file.

We all know that all the “.cpp” (or “.cc” or whatever) files are compiled separately. The obvious result is that the header files that each source file includes must be read and parsed and incorporated into the object file once for each and every source file. This opens up an opportunity for greatly saving on compile time. You see, a typical source code file is usually between 200 to 2000 lines of code itself, but it very often includes tens of thousands of other code in form of included header files. It’s really easy to see for yourself. Just pass your source code file that includes a handful of STL headers to the compiler and tell it only to “preprocess” the code (check your compiler’s documentation.) Look at the resultant file. That’s what the poor compiler receives for each cimpiland.

If you use template classes and functions heavily, the situation becomes even more difficult. Because each template class will be specialized by the compiler for each usage throughout the code. That is, you write a 500-line template class, and use it with 20 different types as template arguments. That’s 10000 lines of code right there, not to mention the fact that the source is now much more complex for the compiler to optimize and generate target code from. Let’s face it, templates are great facilities for generic programming, cleaner design, better performance and general wizardry, but they’re no friend of the compiler’s!

Anyway, suppose that you include <map>, <fstream> and <algorithm> headers (from STL) in almost all of your source code files. Since each file is passed to a separate instance of the compiler, no information is interchanged between the instances and the compiler reads, parses, generates code from and optimizes all the three header files for each source file. This is clearly superfluous. The opportunity I mentioned is right here. If you could somehow do the many steps necessary for processing these files (or at least some of the steps) and store the results and the state of the compiler somewhere (in a file, for example) you wouldn’t have to do that for every source file. You would just read that intermediate state file almost directly into memory and save a lot of time.

This is precisely what using pre-compiled headers is. There are some restrictions however. The headers you want to compile into a PCH file have to be exactly the same and they have to be included in every source file and in exactly the same order. This might mean that some of your source files may include headers that they don’t actually need, but this seldom causes any problem. Also, it is essential that the headers you want to pre-compile be included as exactly the first statements of each source file. Because C++ code (specially preprocessor code) can affect the way other included header files (that are included further in the file) behave, there must not be any code before the inclusion of the headers intended for pre-compilation or that code too, becomes part of the PCH.

One more thing that is necessary is to tell the compiler to stop putting headers into the PCH at some point. This is achieved by putting a “#pragma hdrstop” after all the headers that we intend to be included in the PCH file, and before anything else.

There’s a convenient way to manage all this. We can put all the inclusion statements of all the include files we want to go into the PCH file, along with the pragma directive in a specifically designated header file (let’s call it “PCH.h“) and include this file at the very top of each and every source file (remember: only source files, not other header files.) This ensures that the header files and their order is exactly consistent across all files and removes the need for much duplication of #include statements that might lead to much grief. (As a side note: Don’t Repeat Yourself!)

Now, you tell the compiler to create the PCH, and use it throughout the build. Therefore, you have to change the compile command for exactly one of your source files to create the PCH while it’s being compiled (and put this command at the beginning of the list of files to be compiled in your Makefile or whatever) and change the compile command of all the other source files to only use this newly created PCH file.

Since the precompiled header can become a very big file (many tens or even hundreds of mebi-bytes) and it has to be rebuilt every time either the headers included in it are changed (a genuine requirement) or the source file used to create it changes (imposed, because the code in that file will not be included in the PCH anyway) we can create a dedicated source file just for the purpose of PCH creation. This (e.g.) “PCH.cpp file will be empty except for a single #include <PCH.h> statement. This way, this source file never changes and one cause (however minor) for rebuilding of PCH is eliminated.

For those of you who use IDEs and Microsoft Visual Studio in particular (like myself) here’s how you do it in the VS IDE. First go on and create the said “PCH.h” and “PCH.cpp” files above. Remember to include “PCH.h” in every source file at the very top and remember to add “PCH.cpp” to your project. Also very important is that you must remove all the inclusion statements of the files already included in the PCH from each and every source and header file in your project (it’s best to #define them out (actually #if defined them out,) in case this didn’t work out for you and you wanted them back!

OK. Now you have to tell VS to tell VC that you’re going to use PCH. Go to Project->Properties and in that dialog (while making sure “All Configurations” is selected in the “Configuration” combo box on the top left) Configuration Properties->C/C++->Precompiled Headers. Change the value of “Create/Use Precompiled Header” to “Use…” (with command-line switch of “/Yu”) and change the file name in “Create/Use PCH Through File” to whatever the name of your header is (”PCH.h” in our example) and don’t forget any path prefix it might have (you shouldn’t give an absolute path here, but a path relative to one of your include search path directories or your source file directory.)

This has the effect of setting the compile commands for all your source files to use PCH. But someone has to create it first! Find (in “Solution Explorer” window,) the source file you designated to create the PCH (for example “PCH.cpp”) and (right-click on it and) open it’s “Properties” dialog. While again making sure “All Configurations” is selected (as opposed to just “Debug” or “Release” or whatever), find your way to the same place as before (PCH settings.) These are the build options just for our selected file. Only change the “Create/Use Precompiled Header” to “Create…” (instead of “Use…”) and your all set. You should not change the name of the files (neither the header file nor the resulting PCH file) in this dialog.

Now make a full rebuild of the project. If you’ve done it right, and I haven’t forgotten anything important, and your project is big enough, with this rebuild you should see a great speed up. I have seen build times go from 20-25 minutes to 5 minutes and from 8-9 minutes to 1:50-2 minutes instantly.

I suggest you time your builds before and after the use of PCH (in VS2005, go to Tools, Options…, Projects and Solutions, VC++ Project Settings, Build Timing and set it to “Yes”.)

One thing to note. Sometimes, if your project is large enough, the VC compiler will run out of memory and terminate while building the PCH. In that case, you should append a “/ZmXXX” to all your compile commands, where XXX is the amount of memory in some weird scale and unit. Check the compiler documentation (or follow the build error you get when you run into this problem.) In order to do this inside the IDE, go to you project properties dialog, make sure “All Configurations” is selected, go to “C/C++”, “Command Line” and add the (e.g.) “Zm150″ to the (probably) empty box of “Additional Options”. Experiment with the value a bit to find a suitable value that doesn’t exhaust all your available memory and still allows a build.

I hope this mini-guide comes handy to someone someday! Please let me know of any errors I’ve made, or any omissions or inaccuracies.

C++
programming

Comments (8)

Permalink

Movie List Update