Einzelwarnfehler deaktivieren

114

Gibt es eine Möglichkeit, nur eine einzelne Warnzeile in einer CPP-Datei mit Visual Studio zu deaktivieren?

Wenn ich beispielsweise eine Ausnahme abfange und sie nicht behandle, wird der Fehler 4101 (nicht referenzierte lokale Variable) angezeigt. Gibt es eine Möglichkeit, dies nur in dieser Funktion zu ignorieren, es aber ansonsten in der Kompilierungseinheit zu melden? Im Moment habe ich #pragma warning (disable : 4101)oben in die Datei eingefügt, aber das schaltet sie offensichtlich nur für die gesamte Einheit aus.

Plätzchen
quelle
19
Wenn Sie nur den Typ erwähnen und die Ausnahme nicht benennen, wird keine Warnung angezeigt. ZB catch (const std::exception& /* unnamed */) {.... }. Es beantwortet Ihre Frage nicht, könnte aber Ihr Problem lösen.
Sjoerd

Antworten:

180
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop ) 
Andreas Brinck
quelle
1
@Cookie: Ja, es funktioniert für jeden Code, der den Compiler durchläuft.
Matteo Italia
Eine neuere, präzisere Antwort finden Sie in der Antwort von Daniel Seither weiter unten.
Dan Nissenbaum
4
clangscheint nicht dieses Pragma zu unterstützen, aber Sie können den gleichen Effekt mit erreichen #pragma clang diagnostic push, #pragma clang diagnostic ignored "-Wunused-variable"und #pragma clang diagnostic pop. Siehe "Steuern der Diagnose über Pragmas" im Clang-Benutzerhandbuch
Rampion
Da ich diese Funktion nur selten verwende, werde ich normalerweise auf dieser Seite angezeigt, um mich an die Syntax zu erinnern. Ich habe es nur um einen Aufruf einer veralteten Funktion gelegt, die möglicherweise nie aktualisiert wird, damit mich die Warnung in den Compiler-Listen, die ich religiös scanne, nicht stört.
David A. Gray
Für Visual Studio lautet das Befehlszeilenargument /wd4101. Beachten Sie, dass :zwischen dem Flag und der Nummer kein Normalwert besteht und Sie keine durch Kommas getrennte Liste von Nummern erstellen können. Für andere Compiler könnte es /nowarn:4101stattdessen sein.
Jesse Chisholm
89

Wenn Sie eine Warnung nur in einer einzigen Codezeile unterdrücken möchten, können Sie den suppress Warnspezifizierer verwenden :

#pragma warning(suppress: 4101)
// here goes your single line of code where the warning occurs

Für eine einzelne Codezeile funktioniert dies genauso wie das Schreiben der folgenden:

#pragma warning(push)
#pragma warning(disable: 4101)
// here goes your code where the warning occurs
#pragma warning(pop)
Daniel Seither
quelle
8
Sehr hilfreich! Leider funktioniert es nicht für eine einzelne Zeile, die einen Header enthält, der die Warnung generiert.
Marko Popovic
2
@MarkoPopovic: Der Bezeichner suppressarbeitet mit einer einzelnen, vorverarbeiteten Codezeile. Wenn die folgende Zeile #pragma warning(suppress: ...)eine #includeDirektive ist (die die Datei, auf die durch ihren Parameter verwiesen wird, in die aktuelle Kompilierungseinheit erweitert), gilt der Effekt nur für die erste Zeile dieser Datei. Dies sollte offensichtlich sein, da vom Compiler Warnungen generiert werden. Der Compiler verarbeitet vorverarbeiteten Code.
Unsichtbarer
@IInspectable In diesem Fall würde ich es eine nachbearbeitete Codezeile nennen. vorverarbeitet bedeutet, dass es noch nicht vom Präprozessor übersetzt wurde.
void.pointer
2
@voi: Das "-ed" -Ende kennzeichnet das Partizip Perfekt der Vergangenheit . Es wird verwendet, um auszudrücken, dass etwas in der Vergangenheit geendet hat. Eine "vorverarbeitete" Zeile ist eine Zeile, die vollständig verarbeitet wurde.
Unsichtbarer
29

#pragma Push / Pop sind oft eine Lösung für diese Art von Problemen, aber warum entfernen Sie in diesem Fall nicht einfach die nicht referenzierte Variable?

try
{
    // ...
}
catch(const your_exception_type &) // type specified but no variable declared
{
    // ...
}
Matteo Italia
quelle
6
Dies ist keine Antwort auf die Frage. Zugegeben, dies könnte das Problem von OP lösen, hilft aber zukünftigen Lesern nicht mit einer ähnlichen Frage: "Wie deaktiviere ich eine bestimmte Warnung für einen bestimmten Teil meines Codes?"
Sjoerd
1
@Sjoerd: Drei Personen haben bereits die "offizielle Frage" beantwortet, nach der andere Personen suchen könnten. Stattdessen habe ich versucht, zwischen den Zeilen zu lesen und sein eigentliches Problem zu lösen (eine Minute nach Ihrem Kommentar :P).
Matteo Italia
11
@Sjoerd als zukünftiger Leser Ich bestätige, dass diese Antwort mir tatsächlich geholfen hat.
Mołot
2
@ Mołot: Als ehemaliger Schriftsteller bin ich froh, dass es geholfen hat. =)
Matteo Italia
9

Verwenden Sie #pragma warning ( push )dann #pragma warning ( disable ), geben Sie Ihren Code ein und verwenden Sie ihn #pragma warning ( pop )wie hier beschrieben :

#pragma warning( push )
#pragma warning( disable : WarningCode)
// code with warning
#pragma warning( pop ) 
scharfer Zahn
quelle
8

Beispiel:

#pragma warning(suppress:0000)  // (suppress one error in the next line)

Dieses Pragma gilt für C ++ ab Visual Studio 2005.
https://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

Das Pragma ist NICHT gültig für C # über Visual Studio 2005 bis Visual Studio 2015.
Fehler: "Erwartete Deaktivierung oder Wiederherstellung".
(Ich denke, sie sind nie zur Implementierung gekommen suppress...)
https://msdn.microsoft.com/en-us/library/441722ys(v=vs.140).aspx

C # benötigt ein anderes Format. Es würde so aussehen (aber nicht funktionieren):

#pragma warning suppress 0642  // (suppress one error in the next line)

Stattdessen suppressmüssen Sie disableund enable:

if (condition)
#pragma warning disable 0642
    ;  // Empty statement HERE provokes Warning: "Possible mistaken empty statement" (CS0642)
#pragma warning restore 0642
else

Das ist so hässlich, ich denke, es ist klüger, es einfach neu zu stylen:

if (condition)
{
    // Do nothing (because blah blah blah).
}
else
A876
quelle
5

Statt es auf der Datei des Setzens (oder sogar einer Header - Datei), wickeln Sie einfach den Code in Frage #pragma warning (push), #pragma warning (disable)und eine passende #pragma warning (pop), wie gezeigt hier .

Obwohl es einige andere Optionen gibt, einschließlich #pramga warning (once).

Christian.K
quelle
5

Man kann auch UNREFERENCED_PARAMETERdefiniert in verwenden WinNT.H. Die Definition ist nur:

#define UNREFERENCED_PARAMETER(P)          (P)

Und benutze es wie:

void OnMessage(WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(wParam);
    UNREFERENCED_PARAMETER(lParam);
}

Warum sollten Sie es verwenden? Sie könnten argumentieren, dass Sie den Variablennamen selbst einfach weglassen können. Nun, es gibt Fälle (unterschiedliche Projektkonfiguration, Debug / Release-Builds), in denen die Variable möglicherweise tatsächlich verwendet wird. In einer anderen Konfiguration bleibt diese Variable unbenutzt (und daher die Warnung).

Einige statische Code-Analysen geben möglicherweise immer noch eine Warnung für diese unsinnige Anweisung aus ( wParam;). In diesem Fall können Sie das verwenden, DBG_UNREFERENCED_PARAMETERwas mit UNREFERENCED_PARAMETERDebug-Builds und P=PRelease- Builds identisch ist .

#define DBG_UNREFERENCED_PARAMETER(P)      (P) = (P)
Ajay
quelle
1
Beachten Sie, dass wir seit C ++ 11 [[maybe_unused]]Attribut
Metablaster
2

Wenn Sie das unreferenced local variableSchreiben in einem Header deaktivieren möchten

template<class T>
void ignore (const T & ) {}

und verwenden

catch(const Except & excpt) {
    ignore(excpt); // No warning
    // ...  
} 
Alexey Malistov
quelle
2
Ein Funktionsaufruf, nur um die Warnung zu unterdrücken? Warum machst du das nicht stattdessen : (void)unusedVar;?
Nawaz
@Nawaz: Ich denke, (void)unusedVar;?ist nicht C ++ Standard-konform.
Alexey Malistov
2
Es ist ein Ausdruck, dessen Wert nichts ist. In C ++ können Sie sogar tun static_cast<void>(unusedVar).
Nawaz
2
@ Nawaz. Herb Sutter Erklärung: herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings
Alexey Malistov
2
§5.2.9 / 4 sagt, Any expression can be explicitly converted to type “cv void.” The expression value is discardedwonach Sie schreiben können static_cast<void>(unusedVar)und static_cast<const void>(unusedVar)und static_cast<volatile void>(unusedVar). Alle Formulare sind gültig. Ich hoffe, es klärt Ihren Zweifel.
Nawaz
2

In bestimmten Situationen müssen Sie einen benannten Parameter haben, den Sie jedoch nicht direkt verwenden.
Zum Beispiel bin ich auf VS2010 darauf gestoßen. Wenn 'e' nur in einer decltypeAnweisung verwendet wird, beschwert sich der Compiler, aber Sie müssen die benannte Variable haben e.

Alle oben genannten Nichtvorschläge beschränken sich #pragmadarauf, nur eine einzige Aussage hinzuzufügen:

bool f(int e)
{ 
   // code not using e
   return true;
   e; // use without doing anything
}
Adi Shavit
quelle
1
Jetzt (im MS VS2015-Compiler) verursacht dies C4702 nicht erreichbaren Code
Cee McSharpface
2

Wie @rampion erwähnt hat, sind die Warnungen, wenn Sie sich in clang gcc befinden, nach Name und nicht nach Nummer, und Sie müssen Folgendes tun:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
// ..your code..
#pragma clang diagnostic pop

Diese Info kommt von hier

Orion Elenzil
quelle