开发者

What is the best way to eliminate MS Visual C++ Linker warning : "warning LNK4221"?

I have a CPP source file that uses #if / #endif to compile out completely in certain builds. However, this generates the following warning.

warning LNK4221: no public symbols found; archive member will be inaccessible

I was thinking about creating a macro to generate a dummy variable or function that wouldn't actually be used so this error would go away but I want to make sure that it doesn't cause problems such as using the macro in multiple files causing the linker to bomb on multiply defined symbols.

What is the best way to get rid of this warning (without simply suppressing the warning on the linker command line) ?

FWIW, I would be interested in knowing how to do it by suppressing the warning on the linker command line as well but all my attempts there appear to be simply ignored by the linker and still generate the error.

One other requirement: The fix must be able to stand up to ind开发者_如何学Pythonividual file builds or unity build (combine CPP file builds) since one of our build configurations is a bulk build (like a unity build but groups of bulk files rather than a single master unity file).


Use an anonymous namespace:

namespace { char dummy; };

Symbols within such namespace have external linkage, so there will be something in the export table. On the other hand, the namespace name itself will be distinct (you can think of it as "randomly generated") for every translation unit, so no clashes.


OK, the fix I am going to use is Pavel's suggestion with a minor tweak. The reason I’m using this fix is it’s an easy macro to drop in and it will work in bulk-builds / unity-builds as well as normal builds:

Shared Header:

// The following macro "NoEmptyFile()" can be put into a file
// in order suppress the MS Visual C++ Linker warning 4221
//
// warning LNK4221: no public symbols found; archive member will be inaccessible
//
// This warning occurs on PC and XBOX when a file compiles out completely
// has no externally visible symbols which may be dependant on configuration
// #defines and options.

#define NoEmptyFile()   namespace { char NoEmptyFileDummy##__LINE__; }

File that may compile out completely:

NoEmptyFile()
#if DEBUG_OPTION
      // code
#endif // DEBUG_OPTION


(Though the discussion is already old and I cannot comment directly @Adisak's answer), I guess some additional macro expansion magic is needed for this to work:

#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define NONEMPTY_TRANSLATION_UNIT char TOKENPASTE2(NoEmptyFileDummy, __LINE__);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜