我有一个CPP源文件,使用 #if / #endif 在某些版本中完全编译。但是,这会产生以下警告。
warning LNK4221: no public symbols found; archive member will be inaccessible
我正在考虑创建一个宏来生成一个实际上不会被使用的虚拟变量或函数,因此这个错误会消失但是我想确保它不会导致诸如在多个宏中使用宏的问题导致链接器轰炸多个定义符号的文件。
摆脱此警告的最佳方法是什么(不要简单地抑制链接器命令行上的警告)?
FWIW,我有兴趣知道如何通过抑制链接器命令行上的警告来实现它,但我所有的尝试似乎都被链接器忽略,但仍然会产生错误。
另一个要求:修复必须能够经得起单个文件构建或统一构建(结合CPP文件构建),因为我们的构建配置之一是批量构建(如统一构建但是批量文件组而不是单个主统一文件)。
答案 0 :(得分:20)
使用匿名命名空间:
namespace { char dummy; };
此类命名空间中的符号具有外部链接,因此导出表中会有一些内容。另一方面,命名空间名称本身对于每个翻译单元都是不同的(您可以将其视为“随机生成”),因此不会发生冲突。
答案 1 :(得分:12)
好的,我将要使用的修复是Pavel的建议,只需稍作调整即可。我使用此修复程序的原因是它是一个简单的宏,它将在批量构建/统一构建以及正常构建中工作:
共享标题:
// 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__; }
可能完全编译的文件:
NoEmptyFile()
#if DEBUG_OPTION
// code
#endif // DEBUG_OPTION
答案 2 :(得分:1)
(虽然讨论已经很久了,我无法直接评论@Adisak的答案),但我想还需要一些额外的宏扩展魔法才能实现:
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define NONEMPTY_TRANSLATION_UNIT char TOKENPASTE2(NoEmptyFileDummy, __LINE__);