Freigeben über


Einschränkungen für systemeigene C++-Ausdrücke

Dieses Thema gilt für folgende Anwendungsbereiche:

Edition

Visual Basic

C#

F#

C++

Web Developer

Express

Thema ist nicht vorhanden Thema ist nicht vorhanden Thema ist nicht vorhanden

Nur "Systemeigen"

Thema ist nicht vorhanden

Pro, Premium und Ultimate

Thema ist nicht vorhanden Thema ist nicht vorhanden Thema ist nicht vorhanden

Nur "Systemeigen"

Thema ist nicht vorhanden

Bei der Eingabe eines C/C++-Ausdrucks in einem Debuggerfenster gelten die folgenden allgemeinen Einschränkungen:

Zugriffssteuerung

Der Debugger kann unabhängig von der Zugriffssteuerung auf alle Klassenmember zugreifen. Sie können beliebige Member eines Klassenobjekts, einschließlich Basisklassen und eingebetteten Memberobjekten, überprüfen.

Mehrdeutige Verweise

Wenn ein Debuggerausdruck auf einen mehrdeutigen Membernamen verweist, müssen Sie diesen mithilfe des Klassennamens kennzeichnen. Wenn CObject beispielsweise eine Instanz von CClass ist, die Memberfunktionen mit dem Namen expense sowohl von AClass als auch von BClass erbt, dann ist CObject.expense mehrdeutig. Sie können die Mehrdeutigkeit wie folgt auflösen:

CObject.BClass::expense

Um Mehrdeutigkeiten im Hinblick auf Membernamen aufzulösen, wendet die Ausdrucksauswertung normale Dominanzregeln an.

Anonyme Namespaces

Die systemeigene C++-Ausdrucksauswertung unterstützt keine anonymen Namespaces. Nehmen Sie z. B. an, Sie hätten folgenden Code:

#include "stdafx.h"

namespace mars

{

namespace

{

int test = 0;

}

}

int main()

{

// Adding a watch on test does not work.

mars::test++;

return 0;

}

Hier besteht die einzige Möglichkeit, das Symbol test zu beobachten, in der Verwendung des ergänzten Namens:

(int*)?test@?A0xccd06570@mars@@3HA

Konstruktoren, Destruktoren und Konvertierungen

Es ist weder explizit noch implizit möglich, einen Konstruktor oder Destruktor für ein Objekt mittels eines Ausdrucks aufzurufen, durch den ein temporäres Objekt erstellt wird. Mit dem folgenden Ausdruck wird beispielsweise ein Konstruktor explizit aufgerufen, was eine Fehlermeldung zur Folge hat:

Date( 2, 3, 1985 )

Sie können keine Konvertierungsfunktion aufrufen, wenn es sich beim Ziel der Konvertierung um eine Klasse handelt. Eine solche Konvertierung impliziert die Erstellung eines Objekts. Wenn myFraction beispielsweise eine Instanz von CFraction ist, durch die der Konvertierungsfunktionsoperator FixedPoint definiert wird, verursacht der folgende Ausdruck einen Fehler:

(FixedPoint)myFraction

Ist das Ziel der Konvertierung jedoch ein integrierter Typ, kann eine Konvertierungsfunktion aufgerufen werden. Wenn durch CFraction eine operator float-Konvertierungsfunktion definiert wird, ist der folgende Ausdruck im Debugger zulässig:

(float)myFraction

Sie können Funktionen aufrufen, durch die ein Objekt zurückgegeben oder lokale Objekte deklariert werden.

Der Operator new oder der Operator delete kann nicht aufgerufen werden. Der folgende Ausdruck wird im Debugger nicht ausgeführt:

new Date(2,3,1985)

Vererbung

Wenn Sie den Debugger verwenden, um ein Klassenobjekt anzuzeigen, das über virtuelle Basisklassen verfügt, werden die Member der virtuellen Basisklasse für jeden Vererbungsweg angezeigt, obwohl nur eine Instanz dieser Member gespeichert wird.

Virtuelle Funktionsaufrufe werden von der Ausdrucksauswertung ordnungsgemäß behandelt. Angenommen, die CEmployee-Klasse definiert die virtuelle computePay-Funktion. Diese Funktion wird in einer Klasse, die von CEmployee erbt, neu definiert. Sie können computePay über einen Zeiger auf CEmployee aufrufen und so die geeignete Funktion ausführen lassen:

empPtr->computePay()

Sie können einen Zeiger auf ein abgeleitetes Klassenobjekt in einen Zeigertyp umwandeln, der auf ein Basisklassenobjekt zeigt. Die Typumwandlung in umgekehrter Richtung ist nicht zulässig.

Systeminterne Funktionen und Inlinefunktionen

Ein Debuggerausdruck kann keine integrierte oder Inlinefunktion aufrufen, es sei denn, die Funktion kommt mindestens einmal als normale Funktion im Code vor.

Numerische Konstanten

Debuggerausdrücke können Ganzzahlkonstanten im Oktal-, Hexadezimal- oder Dezimalformat verwenden. Der Debugger erwartet standardmäßig Dezimalkonstanten. Diese Einstellung kann auf der Registerkarte Debuggen und dort auf der Seite Allgemein geändert werden.

Sie können Präfix- oder Suffixsymbole verwenden, um Zahlen in einem anderen Basisformat darzustellen. In der folgenden Tabelle sind die möglichen Formate aufgeführt.

Syntax

Beispiel (dezimal 100)

Basis

Ziffern

100 oder 64

Dezimal oder hexadezimal, je nach der aktuellen Einstellung.

0Ziffern

0144

Oktalformat (Basis 8)

0nZiffern

0n100

Dezimalformat (Basis 10)

0xZiffern

0x64

Hexadezimalformat (Basis 16)

Ziffernh

64h

Hexadezimalformat (Basis 16)

Operatorfunktionen

Ein Debuggerausdruck kann Operatorfunktionen für eine Klasse implizit oder explizit aufrufen. Angenommen, myFraction und yourFraction sind Instanzen einer Klasse, durch die operator+ definiert wird. Die Summe der beiden Objekte kann mit folgendem Ausdruck dargestellt werden:

myFraction + yourFraction

Wenn eine Operatorfunktion als Friend-Funktion definiert ist, kann sie mit derselben Syntax wie für eine Memberfunktion implizit aufgerufen werden; sie kann jedoch auch wie folgt explizit aufgerufen werden:

operator+( myFraction, yourFraction )

Operatorfunktionen können ebenso wenig wie gewöhnliche Funktionen mit Argumenten aufgerufen werden, die eine Konvertierung mit Objekterstellung erfordern.

Der Debugger unterstützt keine überladenen Operatoren mit sowohl const- als auch Nicht-const-Versionen. Überladene Operatoren mit const und Nicht-const-Versionen werden häufig in der Standardvorlagenbibliothek verwendet.

Überladen

Ein Debuggerausdruck kann überladene Funktionen aufrufen, sofern eine exakte Übereinstimmung besteht bzw. die übereinstimmende Funktion keine Konvertierung erfordert, bei der ein Objekt erstellt werden muss. Wenn die calc-Funktion z. B. ein CFraction-Objekt als Parameter hat und die CFraction-Klasse einen Einzelargumentkonstruktor definiert, der eine ganze Zahl akzeptiert, verursacht der folgende Ausdruck einen Fehler:

calc( 23 )

Obwohl es eine zulässige Konvertierung gibt, um die ganze Zahl in das von calc erwartete CFraction-Objekt umzuwandeln, beinhaltet eine derartige Konvertierung die Erstellung eines Objekts und wird daher nicht unterstützt.

Rangfolge

Der C++-Bereichsoperator (::) hat in Debuggerausdrücken einen niedrigeren Stellenwert als in Quellcode. In C++-Quellcode hat dieser Operator absoluten Vorrang. Im Debugger wird dieser Operator vorrangig vor den unären Operatoren (!, &, * u. a.), jedoch erst nach den Operatoren Basis und Postfix (->, ++, --) behandelt.

Symbolformate

Debuggerausdrücke, die Symbole enthalten, werden auf dieselbe Weise wie im Quellcode eingegeben, vorausgesetzt, die Symbole befinden sich in einem Modul, das mit vollständigen Debuginformationen kompiliert wurde (/Zi oder /ZI). Bei der Eingabe eines Ausdrucks mit öffentlichen Symbolen, d. h. Symbolen, die in Bibliotheken oder mit /Zd kompilierten Modulen enthalten sind, müssen Sie den ergänzten Symbolnamen (wie im Objektcode zu finden) verwenden. Weitere Informationen hierzu finden Sie unter /Z7, /Zd, /Zi, /ZI (Debuginformationsformat).

Mithilfe der LINK-Option /MAP erhalten Sie eine Auflistung sämtlicher Namen im ergänzten und nicht ergänzten Format. Weitere Informationen hierzu finden Sie unter "/MAP" (Zuordnungsdatei generieren).

Die Namensergänzung wird verwendet, um typsichere Verknüpfungen zu erzwingen. Dies bedeutet, dass ausschließlich Namen und Verweise miteinander verknüpft werden, deren Rechtschreibung, Groß- und Kleinschreibung, Aufrufkonvention und Typ exakt übereinstimmen.

Mit der C-Aufrufkonvention (entweder implizit oder explizit mit dem _cdecl-Schlüsselwort) deklarierte Namen beginnen mit einem Unterstrich ( _ ). Die Funktion main kann z. B. als _main dargestellt werden. Namen, die als _fastcall deklariert sind, beginnen mit dem @-Symbol.

Bei C++ wird durch den ergänzten Namen neben der Aufrufkonvention auch der Symboltyp codiert. Dieses Namensformat kann sich als lang und schwer lesbar erweisen. Der Name beginnt mit mindestens einem Fragezeichen (?). Bei C++-Funktionen umfasst die Ergänzung den Gültigkeitsbereich der Funktion, die Typen der Funktionsparameter und den Rückgabetyp der Funktion.

Typumwandlung

Bei Verwendung einer Typumwandlung muss der Typ dem Debugger bekannt sein. Das Programm muss über ein weiteres Objekt dieses Typs verfügen. Mithilfe von typedef-Anweisungen erstellte Typen werden nicht unterstützt.

Siehe auch

Weitere Ressourcen

Ausdrücke in systemeigenem C++