Подтвердить что ты не робот

Каков наилучший способ устранения предупреждения MS Visual С++ Linker: "warning LNK4221"?

У меня есть исходный файл CPP, который использует #if/ #endif для полной компиляции в определенных сборках. Однако это вызывает следующее предупреждение.

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

Я думал о создании макроса для создания фиктивной переменной или функции, которая фактически не использовалась бы, чтобы эта ошибка исчезла, но я хочу убедиться, что она не вызывает проблем, таких как использование макроса в нескольких файлы, заставляющие компоновщик бомбить многократно определенные символы.

Каков наилучший способ избавиться от этого предупреждения (без простого предупреждения в командной строке компоновщика)?

FWIW, мне было бы интересно узнать, как это сделать, подавив предупреждение в командной строке компоновщика, но все мои попытки там просто игнорируются компоновщиком и все еще генерируют ошибку.

Еще одно требование: исправление должно поддерживать отдельные сборки файлов или создавать единицу (комбинировать сборки файлов CPP), так как одна из наших конфигураций сборки - это массовая сборка (например, сборка единства, но группы массовых файлов, а не единый файл единственного файла).

4b9b3361

Ответ 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__);