17

我有一个 CPP 源文件,它使用#if / #endif在某些版本中完全编译出来。但是,这会生成以下警告。

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

我正在考虑创建一个宏来生成一个实际上不会使用的虚拟变量或函数,这样这个错误就会消失,但我想确保它不会导致问题,例如在多个文件中使用宏会导致链接器轰炸多重定义的符号。

消除此警告的最佳方法是什么(而不是简单地抑制链接器命令行上的警告)?

FWIW,我很想知道如何通过抑制链接器命令行上的警告来做到这一点,但是我在那里的所有尝试似乎都被链接器忽略并且仍然产生错误。

另一个要求:修复必须能够承受单个文件构建或统一构建(组合 CPP 文件构建),因为我们的构建配置之一是批量构建(如统一构建但批量文件组而不是单个主统一文件)。

4

3 回答 3

20

使用匿名命名空间:

namespace { char dummy; };

此类命名空间中的符号具有外部链接,因此导出表中会有一些内容。另一方面,命名空间名称本身对于每个翻译单元都是不同的(您可以将其视为“随机生成的”),因此不会发生冲突。

于 2009-11-30T22:40:31.837 回答
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
于 2009-11-30T23:00:38.333 回答
1

(虽然讨论已经很老了,我不能直接评论@Adisak的答案),我想这个工作需要一些额外的宏扩展魔法:

#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define NONEMPTY_TRANSLATION_UNIT char TOKENPASTE2(NoEmptyFileDummy, __LINE__);
于 2017-03-01T10:51:51.470 回答