Freigeben über


Hinweisdateien

Eine Hinweisdatei unterstützt die integrierte Entwicklungsumgebung (Integrated Development Environment, IDE) von Visual Studio bei der Interpretation von Visual C++-Bezeichnern, z. B. von Namen von Funktionen und Makros.Beim Öffnen eines Visual C++-Projekts analysiert das Analysesystem der IDE den Code in jeder Quelldatei im Projekt und erfasst Informationen zu allen Bezeichnern.Die IDE unterstützt mithilfe dieser Informationen Features wie den Browser Klassenansicht und die Navigationsleiste.

Das mit Visual C++ 2010 eingeführte Analysesystem versteht die C/C++-Syntax, kann aber eine Anweisung, die ein Makro enthält, möglicherweise falsch interpretieren.Die Anweisung wird möglicherweise falsch interpretiert, wenn das angegebene Makro für einen syntaktisch falschen Quellcode verantwortlich ist.Die Anweisung kann syntaktisch richtig sein, wenn der Quellcode kompiliert wird und der Präprozessor Makrobezeichner durch ihre Definition ersetzt. Das Analysesystem funktioniert, ohne zu müssen, das Projekt zu erstellen, da es Hinweisdateien, um Makros zu interpretieren. Daher ist eine Durchsuchenfunktion wie Klassenansicht sofort verfügbar.

Eine Hinweisdatei enthält vom Benutzer anpassbare Hinweise, die dieselbe Syntax wie C/C++-Makrodefinitionen aufweisen.Visual C++ enthält eine integrierte Hinweisdatei, die für die meisten Projekte ausreichend ist. Sie können jedoch eigene Hinweisdateien erstellen, um die Behandlung von Bezeichnern durch Visual Studio zu verbessern.

Szenario

Angenommen, der folgende Code befindet sich in einer Quelldatei, die Sie mit dem Browser Klassenansicht überprüfen.Das Makro STDMETHOD deklariert die Methode myMethod, die einen Parameter annimmt und einen Zeiger auf einen HRESULT-Wert zurückgibt.

// Source code file.
STDMETHOD(myMethod)(int parameter1);

Die folgenden Makrodefinitionen befinden sich in einer separaten Headerdatei.

// Header file.
#define STDMETHOD(method) HRESULT (STDMETHODCALLTYPE * method)
#define STDMETHODCALLTYPE __stdcall
#define HRESULT void*

Das Analysesystem kann den Quellcode nicht interpretieren, da offenbar eine Funktion mit dem Namen STDMETHOD deklariert wird und diese Deklaration syntaktisch falsch ist, da sie zwei Parameterlisten enthält.Das Analysesystem öffnet die Headerdatei nicht, um die Definitionen für die Makros STDMETHOD, STDMETHODCALLTYPE und HRESULT zu ermitteln.Da das Analysesystem das Makro STDMETHOD nicht interpretieren kann, ignoriert es die ganze Anweisung und setzt die Analyse fort.

Das Analysesystem verwendet keine Headerdateien, da das Projekt von einer oder mehreren wichtigen Headerdateien abhängen könnte.Sobald sich eine Headerdatei ändert, müsste das Analysesystem alle Headerdateien im Projekt erneut prüfen, was die Leistung der IDE verschlechtern würde.Stattdessen verwendet das Analysesystem Hinweise, die angeben, wie die Makros STDMETHOD, STDMETHODCALLTYPE und HRESULT behandelt werden.

Woran ist zu erkennen, dass ein Hinweis benötigt wird?Und wenn ein Hinweis benötigt wird, welche Art von Hinweis soll dann erstellt werden?Ein Zeichen, dass ein Hinweis benötigt wird, ist, wenn die Ansicht eines Bezeichners in der Klassenansicht mit der Ansicht im Editor nicht übereinstimmt.Beispiel: In der Klassenansicht wird ein Klassenmember nicht angezeigt, von dem Sie wissen, dass er vorhanden ist, oder der Name des Members ist falsch.Weitere Informationen zu den Typen von Hinweisen, die allgemeine Probleme beheben, sehen Sie, welche Makros ein Hinweis benötigt wird?Abschnitt weiter unten in diesem Thema.

Architektur

Hinweisdateien beziehen sich auf physische Verzeichnisse, nicht auf die logischen in Projektmappen-Explorer dargestellten Verzeichnisse.Sie müssen dem Projekt keine Hinweisdatei hinzufügen, damit die Hinweisdatei Auswirkungen hat.Das Analysesystem verwendet Hinweisdateien nur, wenn es Quelldateien analysiert.

Jede Hinweisdatei wird cpp.hint genannt.Daher können viele Verzeichnisse eine Hinweisdatei enthalten, aber nur eine Hinweisdatei kann in einem bestimmten Verzeichnis auftreten.

Auf das Projekt können sich keine oder mehrere Hinweisdateien beziehen.Wenn keine Hinweisdateien vorhanden sind, verwendet das Analysesystem nicht entzifferbaren Quellcode mithilfe von Techniken der Wiederherstellung nach einem Fehler.Andernfalls verwendet das Analysesystem die folgende Strategie, um Hinweise zu suchen und zu erfassen.

Dd997977.collapse_all(de-de,VS.110).gifSuchreihenfolge

Das Analysesystem sucht in Verzeichnissen nach Hinweisdateien in der folgenden Reihenfolge.

  • Das Verzeichnis, das das Installationspaket für Visual C++ (vcpackages) enthält.Dieses Verzeichnis enthält eine integrierte Hinweisdatei, die Symbole in häufig verwendeten Systemdateien beschreibt, z. B. windows.h.Infolgedessen erbt das Projekt automatisch die meisten der Hinweise, die es benötigt.

  • Der Pfad vom Stammverzeichnis einer Quelldatei zum Verzeichnis, das die Quelldatei selbst enthält.In einem typischen Visual C++-Projekt enthält das Stammverzeichnis die Projektmappe oder die Projektdatei.

    Die Ausnahme von dieser Regel ist der Fall, dass sich eine Stoppdatei im Pfad zur Quelldatei befindet.Eine Stoppdatei, bei der es sich um jede Datei mit der Bezeichnung cpp.stop handelt, stellt zusätzliche Kontrollmöglichkeiten für die Suchreihenfolge bereit.Statt vom Stammverzeichnis aus zu starten, sucht das Analysesystem von dem Verzeichnis aus, das die Stoppdatei zum Verzeichnis mit der Quelldatei enthält.In einem typischen Projekt benötigen Sie keine Stoppdatei.

Dd997977.collapse_all(de-de,VS.110).gifErfassen von Hinweisen

Eine Hinweisdatei enthält keine oder mehrere Hinweise.Ein Hinweis wird wie ein C/C++-Makro definiert oder gelöscht.Das heißt, die #define-Präprozessordirektive erstellt einen Hinweis oder definiert einen Hinweis neu, und die #undef-Direktive löscht einen Hinweis.

Das Analysesystem öffnet jede Hinweisdatei in der weiter oben beschriebenen Suchreihenfolge, stellt die Hinweise aller Dateien zu effektiven Hinweisen zusammen und interpretiert die Bezeichner im Code mithilfe dieser effektiven Hinweise.

Das Analysesystem sammelt Hinweise mithilfe der folgenden Regeln.

  • Wenn der neue Hinweis einen Namen angibt, der noch nicht definiert ist, fügt der neue Hinweis den effektiven Hinweisen den Namen hinzu.

  • Wenn der neue Hinweis einen Namen angibt, der bereits definiert ist, definiert der neue Hinweis den vorhandenen Hinweis neu.

  • Wenn der neue Hinweis eine #undef-Direktive ist, die einen vorhandenen effektiven Hinweis angibt, löscht der neue Hinweis den vorhandenen Hinweis.

Die erste Regel besagt, dass effektive Hinweise von zuvor geöffneten Hinweisdateien geerbt werden.Die letzten beiden Regeln besagen, dass Hinweise weiter hinten in der Suchreihenfolge Hinweise weiter vorn in der Suchreihenfolge überschreiben können.Sie können z. B. alle vorherigen Hinweise überschreiben, wenn Sie eine Hinweisdatei in dem Verzeichnis erstellen, das eine Quelldatei enthält.

Die Erfassung von Hinweisen wird im Abschnitt Example weiter unten in diesem Thema dargestellt.

Dd997977.collapse_all(de-de,VS.110).gifSyntax

Hinweise werden mit derselben Syntax erstellt und gelöscht, mit der die Präprozessordirektiven Makros erstellen und löschen.Das Analysesystem wertet die Hinweise sogar mithilfe des C/C++-Präprozessors aus.Weitere Informationen zu den Präprozessordirektiven finden Sie unter #define Direktive (C/C++) und #undef Direktive (C/C++).

Die einzigen außergewöhnlichen Syntaxelemente sind die Ersetzungszeichenfolgen @<, @= und @>.Hierbei handelt es sich um für Hinweisdateien spezifische Ersetzungszeichenfolgen, die nur in Verbindung mit Zuordnungsmakros verwendet werden.Eine Zuordnung besteht aus Makros, die Daten, Funktionen oder Ereignisse mit anderen Daten, Funktionen oder Ereignishandlern verknüpfen.Beispiel: MFC verwendet Zuordnungen zum Erstellen von Meldungszuordnungen, und ATL verwendet Zuordnungen zum Erstellen von Objektzuordnungen.Die für Hinweisdateien spezifischen Ersetzungszeichenfolgen geben die Start-, Zwischen- und Endelemente einer Zuordnung an.Nur der Name eines Zuordnungsmakros ist wichtig.Daher blendet jede Ersetzungszeichenfolge die Implementierung des Makros absichtlich aus.

Hinweise verwenden die folgende Syntax.

Syntax

Bedeutung

#defineHinweisnameErsetzungszeichenfolge

#defineHinweisname(Parameter, ...)Ersetzungszeichenfolge

Eine Präprozessordirektive, die einen neuen Hinweis definiert oder einen vorhandenen Hinweis neu definiert.Nach der Direktive ersetzt der Präprozessor jedes Vorkommen von Hinweisname im Quellcode durch Ersetzungszeichenfolge.

Das zweite Syntaxformat definiert einen funktionsähnlichen Hinweis.Wenn ein funktionsähnlicher Hinweis im Quellcode vorkommt, ersetzt der Präprozessor jedes Vorkommen von Parameter in der Ersetzungszeichenfolge durch das entsprechende Argument im Quellcode und anschließend Hinweisname durch die Ersetzungszeichenfolge.

@<

Eine für Hinweisdateien spezifische Ersetzungszeichenfolge, die den Beginn einer Gruppe von Zuordnungselementen angibt.

@=

Eine für Hinweisdateien spezifische Ersetzungszeichenfolge, die ein Zwischenelement der Zuordnung angibt.Eine Zuordnung kann über mehrere Zuordnungselemente verfügen.

@>

Eine für Hinweisdateien spezifische Ersetzungszeichenfolge, die das Ende einer Gruppe von Zuordnungselementen angibt.

#undefHinweisname

Die Präprozessordirektive, die einen vorhandenen Hinweis löscht.Der Name des Hinweises wird vom Hinweisname-Bezeichner angegeben.

//Kommentar

Ein einzeiliger Kommentar.

/*Kommentar*/

Ein mehrzeiliger Kommentar.

Welche Makros erfordern einen Hinweis?

Bestimmte Typen von Makros können das Analysesystem behindern.In diesem Abschnitt werden die Typen von Makros, die ein Problem verursachen können, sowie der Hinweistyp, den Sie zum Beheben dieses Problems erstellen können, beschrieben.

Dd997977.collapse_all(de-de,VS.110).gifStörende Makros

Einige Makros, die ohne Beeinträchtigung des Browsers ignoriert werden können, bewirken, dass das Analysesystem Quellcode falsch interpretiert.Die SAL-Makros (Source Code Annotation Language) werden beispielsweise in C++-Attribute aufgelöst, mit deren Hilfe Sie Programmierfehler finden können.Wenn Sie beim Durchsuchen von Code SAL-Anmerkungen ignorieren möchten, sollten Sie eine Hinweisdatei erstellen, die die Anmerkungen ausblendet.

Im folgenden Quellcode lautet der Parametertyp für die FormatWindowClassName()-Funktion PXSTR, und der Parametername lautet szBuffer.Das Analysesystem verwechselt jedoch die SAL-Anmerkungen _Pre_notnull_ und _Post_z_ mit dem Parametertyp bzw. mit dem Parameternamen.

Quellcode:

static void FormatWindowClassName(_Pre_notnull_ _Post_z_ PXSTR szBuffer)

Strategie: NULL-Definition

Die Strategie in dieser Situation ist, die SAL-Anmerkungen zu behandeln, als ob sie nicht vorhanden waren.Geben Sie hierzu einen Hinweis an, dessen Ersetzungszeichenfolge NULL ist.Infolgedessen ignoriert das Analysesystem die Anmerkungen, und der Browser Klassenansicht zeigt sie nicht an.(Visual C++ enthält eine integrierte Hinweisdatei, die SAL-Anmerkungen ausblendet.)

Hinweisdatei:

#define _Pre_notnull_

Dd997977.collapse_all(de-de,VS.110).gifVerborgene C/C++-Sprachelemente

Ein typischer Grund dafür, dass das Analysesystem Quellcode falsch interpretiert: Ein Makro blendet ein Markierungszeichen oder Schlüsselworttoken in C/C++ aus.Dies ist der Fall, wenn ein Makro beispielsweise nur einen Teil eines Markierungszeichenpaars enthält, z. B. <>, [], {} und ().

Im folgenden Quellcode blendet das Makro START_NAMESPACE die linke geschweifte Klammer ({) aus.

Quellcode:

#define START_NAMESPACE namespace MyProject {

Strategie: direkte Kopie

Wenn die Semantik eines Makros für die Browsererfahrung entscheidend ist, erstellen Sie einen Hinweis, der mit dem Makro identisch ist.Das Analysesystem löst das Makro in die Definition in der Hinweisdatei auf.

Wenn das Makro in der Quelldatei andere Makros enthält, werden diese Makros nur interpretiert, wenn sie sich bereits unter den effektiven Hinweisen befinden.

Hinweisdatei:

#define START_NAMESPACE namespace MyProject {

Dd997977.collapse_all(de-de,VS.110).gifZuordnungen

Eine Zuordnung besteht aus Makros, die ein Startelement, ein Endelement und keine oder mehrere Zwischenelemente festlegen.Das Analysesystem interpretiert Zuordnungen falsch, da jedes Zuordnungsmakro C/C++-Sprachelemente ausblendet und die Syntax einer vollständigen C/C++-Anweisung auf viele separate Makros verteilt wird.

Der folgende Quellcode definiert die Makros BEGIN_CATEGORY_MAP, IMPLEMENTED_CATEGORY und END_CATEGORY_MAP.

Quellcode:

#define BEGIN_CATEGORY_MAP(x)\
static const struct ATL::_ATL_CATMAP_ENTRY* GetCategoryMap() throw() {\
static const struct ATL::_ATL_CATMAP_ENTRY pMap[] = {
#define IMPLEMENTED_CATEGORY( catid ) { _ATL_CATMAP_ENTRY_IMPLEMENTED, &catid },
#define END_CATEGORY_MAP()\
   { _ATL_CATMAP_ENTRY_END, NULL } };\
   return( pMap ); }

Strategie: Identifizieren Sie Zuordnungselemente

Geben Sie Hinweise für Start- und Endelemente sowie ggf. für Zwischenelemente einer Zuordnung an.Verwenden Sie die speziellen Ersetzungszeichenfolgen @<, @= und @> für Zuordnungen.Weitere Informationen finden Sie im Abschnitt Syntax in diesem Thema.

Hinweisdatei:

// Start of the map.
#define BEGIN_CATEGORY_MAP(x) @<
// Intermediate map element.
#define IMPLEMENTED_CATEGORY( catid ) @=
// Intermediate map element.
#define REQUIRED_CATEGORY( catid ) @=
// End of the map.
#define END_CATEGORY_MAP() @>

Dd997977.collapse_all(de-de,VS.110).gifZusammengesetzte Makros

Zusammengesetzte Makros enthalten ein oder mehrere Makros, die das Analysesystem durcheinanderbringen.

Der folgende Quellcode enthält das Makro START_NAMESPACE, das den Beginn eines Namespacebereichs angibt, und das Makro BEGIN_CATEGORY_MAP, das den Beginn einer Zuordnung angibt.

Quellcode:

#define NSandMAP START_NAMESPACE BEGIN_CATEGORY_MAP

Strategie: direkte Kopie

Erstellen Sie Hinweise für die Makros START_NAMESPACE und BEGIN_CATEGORY_MAP, und erstellen Sie dann einen Hinweis für das Makro NSandMAP, bei dem es sich um das weiter oben für den Quellcode dargestellte Makro handelt.Alternativ können Sie auch einen Hinweis definieren, dessen Ersetzungszeichenfolge eine NULL-Definition ist, wenn ein zusammengesetztes Makro nur aus störenden Makros und Leerstellen besteht.

In diesem Beispiel enthält START_NAMESPACE bereits einen Hinweis wie in diesem Thema unter der Überschrift Concealed C/C++ Language Elements beschrieben.Zudem enthält BEGIN_CATEGORY_MAP einen Hinweis wie im Abschnitt Maps beschrieben.

Hinweisdatei:

#define NSandMAP START_NAMESPACE BEGIN_CATEGORY_MAP

Dd997977.collapse_all(de-de,VS.110).gifUmständliche Makros

Einige Makros können vom Analysesystem zwar interpretiert werden, der Quellcode ist jedoch schwierig zu lesen, da das Makro lang oder komplex ist.Aus Gründen der Lesbarkeit können Sie einen Hinweis bereitstellen, der die Anzeige des Makros vereinfacht.

Quellcode:

#define STDMETHOD(methodName) HRESULT (STDMETHODCALLTYPE * methodName)

Strategie: Vereinfachung

Erstellen Sie einen Hinweis, der eine einfachere Makrodefinition anzeigt.

Hinweisdatei:

#define STDMETHOD(methodName) void* methodName

Beispiel

Im folgenden Beispiel wird veranschaulicht, wie Hinweise aus Hinweisdateien zusammengefasst werden.Stoppdateien werden in diesem Beispiel nicht verwendet.

Die folgende Abbildung stellt einige physische Verzeichnisse in einem Visual C++-Projekt dar.Hinweisdateien befinden sich in den Verzeichnissen vcpackages, Debug, A1 und A2.

Dd997977.collapse_all(de-de,VS.110).gifHinweisdateiverzeichnisse

Allgemeine und projektspezifische Hinweisdateiverzeichnisse.

Dd997977.collapse_all(de-de,VS.110).gifVerzeichnisse und Hinweisdateiinhalte

In der folgenden Tabelle sind die Verzeichnisse in diesem Projekt, die Hinweisdateien enthalten, und der Inhalt dieser Hinweisdateien aufgeführt.Es sind nur einige der vielen Hinweise in der Verzeichnishinweisdatei vcpackages aufgeführt.

Verzeichnis

Hinweisdateiinhalt

vcpackages

// vcpackages (partial list)
#define _In_
#define _In_opt_
#define _In_z_
#define _In_opt_z_
#define _In_count_(size)

Debug

// Debug
#undef _In_
#define OBRACE {
#define CBRACE }
#define RAISE_EXCEPTION(x) throw (x)
#define START_NAMESPACE namespace MyProject {
#define END_NAMESPACE }

A1

// A1
#define START_NAMESPACE namespace A1Namespace {

A2

// A2
#undef OBRACE
#undef CBRACE

Dd997977.collapse_all(de-de,VS.110).gifEffektive Hinweise

In der folgenden Tabelle sind die effektiven Hinweise für die Quelldateien in diesem Projekt aufgeführt.

Quelldatei

Effektive Hinweise

A1_A2_B.cpp

// vcpackages (partial list)
#define _In_opt_
#define _In_z_
#define _In_opt_z_
#define _In_count_(size)
// Debug...
#define RAISE_EXCEPTION(x) throw (x)
// A1
#define START_NAMESPACE namespace A1Namespace { 
// ...Debug
#define END_NAMESPACE }

Die folgenden Hinweise gelten für die vorangehende Tabelle.

  • Die effektiven Hinweise stammen aus den Verzeichnissen vcpackages, Debug, A1 und A2.

  • Die #undef-Direktive in der Hinweisdatei Debug hat den #define _In_-Hinweis in der Verzeichnishinweisdatei vcpackages entfernt.

  • Die Hinweisdatei im Verzeichnis A1 definiert START_NAMESPACE neu.

  • Der Hinweis #undef im Verzeichnis A2 hat die Hinweise für OBRACE und CBRACE in der Verzeichnishinweisdatei Debug entfernt.

Siehe auch

Referenz

#define Direktive (C/C++)

#undef Direktive (C/C++)

Meldungszuordnungen (MFC)

Konzepte

Für Visual C++-Projekte erstellte Dateitypen

SAL Anmerkungen

Weitere Ressourcen

Erstellen und Steuern von Umgebungsfenstern

Meldungszuordnungs-Makros (ATL)

Objektzuordnungs-Makros