2009-11-30 2 views
17

Ich habe eine CPP-Quelldatei, die #if/#endif verwendet, um vollständig in bestimmten Builds kompilieren. Dies erzeugt jedoch die folgende Warnung.Was ist der beste Weg, MS Visual C++ Linker Warnung zu beseitigen: "Warnung LNK4221"?

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

Ich dachte über ein Makro Erstellen einer Dummy-Variable oder eine Funktion zu erzeugen, die nicht tatsächlich verwendet werden würde, so würde dieser Fehler gehen weg, aber ich möchte sicherstellen, dass es keine Probleme verursacht, wie die Verwendung von das Makro in mehreren Dateien verursacht, dass der Linker auf mehrfach definierte Symbole bombardiert.

Was ist der beste Weg, diese Warnung loszuwerden (ohne die Warnung in der Linker-Befehlszeile einfach zu unterdrücken)?

FWIW, ich wäre daran interessiert zu wissen, wie es geht, indem Sie die Warnung auf der Linker-Befehlszeile auch unterdrücken, aber alle meine Versuche dort scheinen einfach vom Linker ignoriert zu werden und immer noch den Fehler zu erzeugen. Eine andere Anforderung: Die Korrektur muss in der Lage sein, einzelnen Dateierstellungen oder Unity-Builds standzuhalten (CPP-Datei-Builds kombinieren), da eine unserer Build-Konfigurationen ein Bulk-Build ist (wie ein Unity-Build, aber Gruppen von Bulk-Dateien) als eine einzelne Master-Unity-Datei).

+0

Welche Syntax für den Aufruf des Linkers haben Sie versucht (und es hat nicht für Sie funktioniert)? –

+0

Ich habe "/ ignore: 4221" für Linker und "#pragma warning (disable: 4221)" für die cpp-Datei ausprobiert. Keine funktionierte. – Adisak

+0

Nebenbei - was ist der Zweck der 'Einheitsbildung'? –

Antwort

12

OK, der Fix, den ich verwenden werde, ist Pavels Vorschlag mit einer kleinen Verbesserung. Der Grund, warum ich dieses Update bin mit ist es eine einfache Makro in fallen zu lassen, und es wird in Arbeit bulk-Builds/Einheit-Builds sowie normale baut:

Geteilt Rubrik:

// 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__; } 

-Datei, kann vollständig kompilieren aus:

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

einen anonymen Namespace verwenden:

namespace { char dummy; }; 

Symbole innerhalb eines solchen Namensraum externe Bindung haben, so wird es etwas in der Exporttabelle sein. Auf der anderen Seite wird der Namespace-Name selbst für jede Übersetzungseinheit eindeutig sein (Sie können es sich als "zufällig generiert" vorstellen), also keine Konflikte.

+1

Ich werde das testen. Ich brauche es, um mit Unity-Builds zu arbeiten, also muss ich es vielleicht zu einem Makro machen mit "char dummy ## __ LINE__;" oder so, also habe ich keine replizierten Symbole in einer einzigen Übersetzungseinheit. – Adisak

+0

Nun, ich glaube nicht, dass Sie mehr als eine pro Einheit brauchen würden. – GManNickG

+0

Die Reparatur hier bombardiert unsere Einheit wie erwartet, aber es sollte mit dem kleinen Mod funktionieren, den ich beschrieben habe. – Adisak

1

(Obwohl die Diskussion schon alt, und ich kann nicht direkt @ Adisak Antwort Kommentar), ich denke, einige zusätzliche Makroerweiterung Magie benötigt wird, damit dies funktioniert:

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