While cleaning up code warnings I came across LNK4221: “xxx.obj: no public symbols found; archive member will be inaccessible.”. The message does point out the culprit obj file, but not much more. both the documentation and a knowledge base article don’t shed much additional light. Generally, it seems i’m not the only one who couldn’t readily identify the problem source. although useful discussions do exist, they’re hidden deep below other search results – so I figured the issue is worth a post.
‘Public symbols’ basically means stuff that the linker can use: functions that can be called, classes that can be instantiated or variables to referenced. (note, we mean compiled functions or classes, as the linker doesn’t do compilation). So far I came across two scenarios that result in compilation units lacking any of those:
(1) A template-only file, typically a header file (since VC++ does not conform to the standard regarding the export keyword). Maybe a class-wizard created a stub cpp for you, or maybe – out of habit – you did it yourself, but there’s really nothing to compile here. All you want is the header to be included wherever the templates are used – the right solution is to discard the cpp altogether.
(2) A cpp that contains real stuff, but one that is compiled only in certain configurations – e.g. debugging facilities, surrounded by #ifdef _DEBUG’s. Can’t say I have an elegant solution for this one – if you’re obliged to zero-warning compilation, you can add to the file a dummy variable (or other symbol) that’s not conditionally compiled. While it may add some miliseconds to link time, rest assured it would be optimized away and have zero effect in production builds.