# Tricky C/C++ Preprocessor Question

**URL:** <https://boards.straightdope.com/t/tricky-c-c-preprocessor-question/265953>\
**Category:** Factual Questions\
**Created:** [September 24, 2004, 10:26pm UTC](https://boards.straightdope.com/t/tricky-c-c-preprocessor-question/265953 "2004-09-24T22:26:03Z")\
**Posts on this page:** 5\
**Page:** 3

<div class="post-metadata">

**Author:** ![z\_z\_z](https://avatars.discourse-cdn.com/v4/letter/z/b2d939/32.png) [@z\_z\_z](https://boards.straightdope.com/u/z_z_z)\
**Post date:** [September 28, 2004, 10:43pm UTC](https://boards.straightdope.com/t/tricky-c-c-preprocessor-question/265953/41 "2004-09-28T22:43:57Z")

</div>

> [@MaxTheVool](#):
>
> \<snip\>
> 
> And it’s nice to be able to expose certain variables to them for tuning purposes.
> 
> \<snip\>
> 
> Here’s another example of a situation when a technique like this was useful: Many games have a dynamic object system in which many different object types (Player, Gun, Bullet, SpecialEffect) all derive from the same base class, and an object factory creates, deletes, and updates these objects. For various reasons, it’s extremely useful to have a list of all possible object types, and be able to refer to objects, and create objects, via an INT type. Ie, ObjectFactory::CreateObject(int iObjectType, void \*pInitData). Thus, we want to be able to assign all the object types numbers, starting with zero, so player = 0, gun = 1, bullet = 2, etc.
> 
> \<snip\>

Hey \*\* MaxTheVool \*\* don´t get me wrong, but since you asked the question, and I suggested some solutions (although I was wrong on some preprecessor replacement issues), I think you owe us further explanations 🙂 Seriously, I am really interested in that.

First: How exactly do you expose your variables to the artists (in a debugger sense, as you implied)? With those weird macros you proposed? How does that expose variables to the artists? Why not spew out a lenghty trace of everything, with different info/warning/error levels, and maybe artist/programmer/supervisor ratings as well? That is always helpful, and from the output of a well designed tracer you can easily extract all sorts of helpful information, including performance data, with scripts or spreadsheets or other tools.

Second: I´m not convinced of your inheritance hierarchy (as outlined in the second paragraph I qouted). That seems, to me, like an abuse of inheritance. Sure, not everything is always textbook perfect. But why use inheritance, and not simply different objects, and aggregation? Using INT types to refer to different classes sounds extremly contrived to me, like inventing another type system instead of what is already in place.

Again, don´t get me wrong, but the more I think about your posts the more I get the impression that you want to work AGAINST to language, instead of taking advantage of what it offers.

---

<div class="post-metadata">

**Author:** ![CaveMike](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/cavemike/32/16379_2.png) [@CaveMike](https://boards.straightdope.com/u/CaveMike)\
**Post date:** [September 29, 2004, 1:40am UTC](https://boards.straightdope.com/t/tricky-c-c-preprocessor-question/265953/42 "2004-09-29T01:40:13Z")

</div>

> [@MaxTheVool](#):
>
> Because to do so would require that any time a new object type is added, a line is added to main(), which makes it harder to keep ones work localized, requires programmers to fight to check out a central file, etc.

**Max** , there is a solution to this problem as well as the static initialization order and I believe you even identified it early in this thread. Include an init() function for each file that has static variables. This init() function can initialize statics, register them with the debug database, and allocate a type-identifier. Adding new static variables to a file would only require a change to that file’s init() function. The only time you would need to change the main() file is when a new file is added to the project which is pretty rare.

---

<div class="post-metadata">

**Author:** ![MaxTheVool](https://avatars.discourse-cdn.com/v4/letter/m/9fc29f/32.png) [@MaxTheVool](https://boards.straightdope.com/u/MaxTheVool)\
**Post date:** [October 4, 2004, 12:15am UTC](https://boards.straightdope.com/t/tricky-c-c-preprocessor-question/265953/43 "2004-10-04T00:15:08Z")

</div>

> [@emarkp](#):
>
> Wait a minute. You mean there are static initializers in multiple files? Well, your order-of-operations is completely unknown then.

True, but it doesn’t matter. There’s a single global instance of an object-manager class. It has a function that’s something like RegisterObjectType(). Inside that function it checks a static variable to see whether it itself has been initialized, and if it hasn’t, initializes itself. Then it doesn’t matter what order everything happens in.

> [@](#):
>
> Do you really add initialization that frequently?

Yes

> [@](#):
>
> Do you know about the PImpl idiom for source code firewalling (which decouples a lot of #include dependency)?

Not by name, although I was familiar with the concept. I don’t see how it’s automatically a win.

> [@](#):
>
> Do you really use a revision control system that doesn’t allow merging?

No, although merging is always a pain. And it’s frequently more a case of touching a central .h file forcing a 250 file recompile instead of a 1 file recompile.

> [@](#):
>
> I strongly suspect that you have many incorrect ideas about the portions you believe you understand. Check out some of the books I listed, even if you just page through them at the local bookstore. You might be surprised at how useful it is to learn to better use your tools.

Quite possibly.

---

<div class="post-metadata">

**Author:** ![MaxTheVool](https://avatars.discourse-cdn.com/v4/letter/m/9fc29f/32.png) [@MaxTheVool](https://boards.straightdope.com/u/MaxTheVool)\
**Post date:** [October 4, 2004, 12:41am UTC](https://boards.straightdope.com/t/tricky-c-c-preprocessor-question/265953/44 "2004-10-04T00:41:01Z")

</div>

> [@z\_z\_z](#):
>
> First: How exactly do you expose your variables to the artists (in a debugger sense, as you implied)? With those weird macros you proposed? How does that expose variables to the artists? Why not spew out a lenghty trace of everything, with different info/warning/error levels, and maybe artist/programmer/supervisor ratings as well? That is always helpful, and from the output of a well designed tracer you can easily extract all sorts of helpful information, including performance data, with scripts or spreadsheets or other tools.

I’m not quite sure what you’re talking about about tracing. I’m talking here about a way to tune things on the fly, as opposed to a way to find bugs. Basically, there’s a function which registers particular variables with the debug menu so that they artists and designers can then have an interface to tune Player::fHitSpeed, or whatever variables the programmers decide to expose to them, with the variables mentioned by name, tuning parameters set, a way to automatically save the tuned variables out to a .ini file, etc.

> [@](#):
>
> Second: I´m not convinced of your inheritance hierarchy (as outlined in the second paragraph I qouted). That seems, to me, like an abuse of inheritance. Sure, not everything is always textbook perfect. But why use inheritance, and not simply different objects, and aggregation? Using INT types to refer to different classes sounds extremly contrived to me, like inventing another type system instead of what is already in place.

Once again… what? We have a base entity class (EntityBaseClass), and many other entity types are derived from it. In a few cases, the tree is more complex (AIBaseClass derives from EntityBaseClass, various classes derive from it). What’s so wrong with this?

As for using INTs, that’s partly a holdover from the days when I was doing all of this in C using function tables and message functions, but it’s also quite useful at times. For instance, if the entity manager keeps lists of entities sorted by type, if the types are represented by INTs 0…n-1, it’s easy to keep an array of list, for loop over that array, etc.

---

<div class="post-metadata">

**Author:** ![MaxTheVool](https://avatars.discourse-cdn.com/v4/letter/m/9fc29f/32.png) [@MaxTheVool](https://boards.straightdope.com/u/MaxTheVool)\
**Post date:** [October 4, 2004, 1:00am UTC](https://boards.straightdope.com/t/tricky-c-c-preprocessor-question/265953/45 "2004-10-04T01:00:40Z")

</div>

> [@CaveMike](#):
>
> **Max** , there is a solution to this problem as well as the static initialization order and I believe you even identified it early in this thread. Include an init() function for each file that has static variables. This init() function can initialize statics, register them with the debug database, and allocate a type-identifier. Adding new static variables to a file would only require a change to that file’s init() function. The only time you would need to change the main() file is when a new file is added to the project which is pretty rare.

I agree that that would do the job just as well…

[Previous page](https://boards.straightdope.com/t/tricky-c-c-preprocessor-question/265953.md?page=2)
