Каков наилучший способ устранения предупреждения MS Visual С++ Linker: "warning LNK4221"?
У меня есть исходный файл CPP, который использует #if/ #endif для полной компиляции в определенных сборках. Однако это вызывает следующее предупреждение.
warning LNK4221: no public symbols found; archive member will be inaccessible
Я думал о создании макроса для создания фиктивной переменной или функции, которая фактически не использовалась бы, чтобы эта ошибка исчезла, но я хочу убедиться, что она не вызывает проблем, таких как использование макроса в нескольких файлы, заставляющие компоновщик бомбить многократно определенные символы.
Каков наилучший способ избавиться от этого предупреждения (без простого предупреждения в командной строке компоновщика)?
FWIW, мне было бы интересно узнать, как это сделать, подавив предупреждение в командной строке компоновщика, но все мои попытки там просто игнорируются компоновщиком и все еще генерируют ошибку.
Еще одно требование: исправление должно поддерживать отдельные сборки файлов или создавать единицу (комбинировать сборки файлов CPP), так как одна из наших конфигураций сборки - это массовая сборка (например, сборка единства, но группы массовых файлов, а не единый файл единственного файла).
Ответы
Ответ 1
ОК, исправление, которое я собираюсь использовать, - предложение Павла с незначительной настройкой. Причина, по которой я использую это исправление, - это простой макрос, который запустится, и он будет работать в build-builds/unity-builds, а также в обычных сборках:
Общий заголовок:
// 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
Использовать анонимное пространство имен:
namespace { char dummy; };
Символы внутри такого пространства имен имеют внешнюю связь, поэтому в таблице экспорта будет что-то. С другой стороны, само имя пространства имен будет отличаться (вы можете считать его "случайным образом" ) для каждой единицы перевода, поэтому никаких столкновений не происходит.
Ответ 3
(Несмотря на то, что обсуждение уже устарело, и я не могу напрямую комментировать ответ @Adisak), я думаю, для этого требуется дополнительная магия для расширения макросов:
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define NONEMPTY_TRANSLATION_UNIT char TOKENPASTE2(NoEmptyFileDummy, __LINE__);