Expert Texture Home Contact me About Subscribe Digipede Connect on LinkedIn rwandering on Twitter rwandering on FriendFeed

rwandering.net

The blogged wandering of Robert W. Anderson

Perils of #define

A couple of years ago, I wrote Three deficiencies in the C# preprocessor.  Those issues still exist, but a good thing about C# is you don’t get the following problem . . .

I’m working on a project for a customer that includes upgrading a VC++ 6.0 DLL to VC++ 2008.  There are some good resources on MSDN for breaking changes (for a starting point, see http://msdn.microsoft.com/en-us/library/bb531344.aspx).  Of course, I didn’t start there, I started by just trying it.  Pretty quickly I came across some of the breaking changes related to STL (specifically that iterators cannot be treated as pointers).

But I also had a pretty bewildering problem.  Hundreds of the following errors:

error C2371: 'std::tr1::placeholders::ks' : redefinition; different basic types 

The source of the error was C:\Program Files\Microsoft Visual Studio 9.0\VC\include\xxbind1, line 298. Looking there, I found:

    // PLACEHOLDER ARGUMENTS
        namespace placeholders {    // placeholders
static _Ph<_NARGS> _CLASS_NAME(_);
        }    // namespace placeholders

Doing some investigation I found that xxbind1 is related to the TR1 extensions to the Standard Library.  The errors didn’t help me figure out where my code was including this file, so using the process of elimination (and the trusty binary search), I found that excluding the STL map header (i.e., <map>) solved this problem.  Not an option, though, since the code in question relies on stl::map.

So, I tried several other avenues to figure out what I was doing wrong.  While scouring all the application header files leading up to this include, I found the following line:

#define _    ks._

I thought, “wow, that looks awfully general for a preprocessor constant in the main internal header file”.  Going back to the code in xxbind1, now that error makes sense.

Removed it, and everything is fine. 

Arbitrary string-replacement before compilation is a powerful thing, but it can allow seemingly unrelated and unintended havoc.

Tags: , ,

    Trackback

1 Comment »