I'm converting what were formerly separate DLL and EXE modules of an MFC application (that is itself based on combining two disparate codebases) into static library (LIB) projects. I took steps to ensure that resource IDs are all unique, but I'm getting a linker error claiming there's duplicate string resources when it links the .res files compiled from different projects' .rc files.
Thing is, the resource ID's the linker says are duplicate do not match any of my resource ID's in use. I figured out by trial and error (and the reported "size" which does match the string resource) that, for each string, the ID being used for the string table resource does not match the one defined by the constant from Resource.h. It's "semi" deterministic in that if, e.g., 3646 gets mapped to 228 then 3647 will be compiled as 229, however the basis value is different for different compilation units, and there seems to be a modulo applied too.
You can see these values by adding the /v (verbose) option in the resource compiler properties page for the project.
That is, if A is the string ID value from Resource.h, what the resource compiler will actually write to the .res file, B, seems to be something like:
B = (A - x) mod y
For some unknown x and y. It might not actually even be modulus; I can't pin it down.
WTF is going on here? Somehow loading the string resource still finds the resource at runtime (assuming linking was successful), but it causes conflicts on linking two different .res files because of the different basis (x) or modulo (y) results in B having the same value for different A.
Actual output from compiler (using /v arg to resource compilation step):
1>Writing AFX_DIALOG_LAYOUT:3508, lang:0x409, size 2.
1>Writing AFX_DIALOG_LAYOUT:3606, lang:0x409, size 2.
1>Writing AFX_DIALOG_LAYOUT:84, lang:0x409, size 2.
1>Writing AFX_DIALOG_LAYOUT:3502, lang:0x409, size 2.............................................................................................
1>Writing STRING:227, lang:0x409, size 278
1>Writing STRING:228, lang:0x409, size 190
1>Writing STRING:229, lang:0x409, size 302
1>Writing STRING:231, lang:0x409, size 740
In the above, 3508, 3606, 84, and 3502 are actual dialog ID values. Based on definitions of the symbols from Resource.h the string resources should be ID's numbering above 3000, not in the 200s. (The sizes match & I can prove it's that string by adding/removing characters and the size reported changes.) The same thing happens when I put literal numeric values in the .rc file instead of using macros from Resource.h.