From: Warren Young Date: December 12 2007 10:35pm Subject: Re: Linking errors after moving to SSQLSs, macro problem List-Archive: http://lists.mysql.com/plusplus/7260 Message-Id: <47606227.3070603@etr-usa.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Simon Pickles wrote: > > My app was building and running without using SSQLS, but seeing the > simplicity and extra functionality they afford, I moved to SSQLS. A search for those errors on the list would have turned up the answer. We've certainly talked about it enough times. The next version of the user manual covers it explicitly: > It's convenient to define an SSQLS in a header file so you can use it in multiple modules. You run into a bit of a problem, though, because each SSQLS includes a few static data members to hold information common to all structures of that type. (The table name and the list of field names.) When you #include that header in more than one module, you get a multiply-defined symbol error at link time. > > The way around this is to define the preprocessor macro MYSQLPP_SSQLS_NO_STATICS in all but one of the modules that use the header definining the SSQLS. When this macro is defined, it suppresses the static data members in any SSQLS defined thereaftear. > > Imagine we have a file my_ssqls.h which includes a sql_create_N macro call to define an SSQLS, and that that SSQLS is used in at least two modules. One we'll call foo.cpp, and we'll say it's just a user of the SSQLS; it doesn't "own" it. Another of the modules, my_ssqls.cpp uses the SSQLS more heavily, so we've called it the owner of the SSQLS. If there aren't very many modules, this works nicely: > > // File foo.cpp, which just uses the SSQLS, but doesn't "own" it: > #define MYSQLPP_SSQLS_NO_STATICS > #include "my_ssqls.h" > > // File my_ssqls.cpp, which owns the SSQLS, so we just #include it directly > #include "my_ssqls.h" > > If there are many modules that need the SSQLS, adding all those #defines can be a pain. In that case, it's easier if you flip the above pattern on its head: > > // File my_ssqls.h: > #if !defined(EXPAND_MY_SSQLS_STATICS) > # define MYSQLPP_SSQLS_NO_STATICS > #endif > sql_create_X(Y, Z....) // the SSQLS definition > > // File foo.cpp, a mere user of the SSQLS: > #include "my_ssqls.h" > > // File my_ssqls.cpp, which owns the SSQLS: > #define EXPAND_MY_SSQLS_STATICS > #include "my_ssqls.h" > > Note that due to a compiler limitation, you can't use the MYSQLPP_SSQLS_NO_STATICS feature with Visual C++ 2003. As instructed in README.vc, you have to disable this feature in order to get the SSQLS header files to compile. Having done that, the SSQLS feature works fine as long as you can live with using each structure type in a single module. Visual C++ 2005 and newer don't suffer from this limitation.