简体   繁体   中英

static char * vs #define in C++ VS2005

I have a large program with several large DLL's that are compiled with MFC and /clr. There is a limit of 65535 global FieldRVA entries in an assembly. If it is more the loader raises an exception. I already have Enable String Pooling (/GF).

I have alot of code like:

static char *pSTRING_ONE = "STRING_ONE";

if I compile witha macro such as:

#define pSTRING_ONE  "STRING_ONE"

it greatly reduces string for the CLR meta data so I compile but then I gain all of the problems of using a #define .

The question is: Is there another alternative to changing the static char * -> #define ?

From MSDN:

http://msdn.microsoft.com/en-us/library/s0s0asdt.aspx

"The /GF compiler option creates an addressable section for each unique string. And by default, an object file can contain up to 65,536 addressable sections. If your program contains more than 65,536 strings, use the /bigobj compiler option to create more sections."

Sounds like /bigobj is your friend here...

Instead of storing the strings in the data segment of your program (since you apparently have a TON of strings), much better is to have a resource file that contains them. Then just dynamically allocate a pool of strings and load the string resource file at program startup. This should totally eliminate the problem in question.

If that's not an option, assuming those are contained at file scope, why are you making the strings static ? That's just the C way (and deprecated in C++) of saying "file scope only". const char *pSTRING_ONE = "STRING_ONE"; would create a global string shared across all the translation units. In this case beset is to just create one file that contains all the strings and then refer to them via extern declarations in a header.

What happens if you don't use /GF ? From Bukes' answer it appears that by pooling strings you're causing the compiler to create one segment per string.

Unfortunately, the best solution to our problem was to include the offending code within a class.

// Old Way
static char *pSTRING_ONE = "STRING_ONE";

New

class CFieldDefs
{
  public:
     static char *pSTRING_ONE;
}

char *CFieldDefs::pSTRING_ONE = "STRING_ONE";

Usage:

CFieldDefs:pSTRING_ONE;

Even though the change was quite tedious, it greatly reduced the number of fieldRVA Entries CLR Fields within the DLL. Thanks for all your help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM