Udostępnij za pośrednictwem


Wyrażenia w natywnym kodzie C++

Debuger akceptuje większości wyrażeń Microsoft i ANSI C/C++.Zapewnia także debugera Funkcje i operatorów kontekst dokonanie oceny wyrażenia, bezpieczniejsze i wygodniejsze.W tym temacie opisano na wyrażeniach języka C++, które trzeba zdawać sobie sprawę z następujących ograniczeń:

Nie można użyć operatora kontekstu lub większości specyfikatory formatu w kodzie lub przy użyciu skryptu lub zarządzany kod wyrażeń.Są one zależne macierzystym C++ szacującego.

W tej sekcji

Przy użyciu funkcji intrinisic debugera, aby utrzymać stan

Aby określić symbol za pomocą operatorów kontekstu

Ograniczenia dotyczące wyrażeń macierzystym C++

  • Kontrola dostępu

  • Niejednoznacznych odwołań

  • Anonimowe przestrzenie nazw

  • Konstruktory, destruktory i konwersje

  • Dziedziczenie

  • Funkcje wewnętrzne Wplatany i kompilatora

  • Stałe numeryczne

  • Operator funkcji

  • Przeciążenie

  • Pierwszeństwo

  • Formaty symbol

  • Typ rzutowania

Przy użyciu funkcji intrinisic debugera, aby utrzymać stan

Funkcje wewnętrzne debugera dają sposobem na połączenie niektórych funkcji C/C++ w wyrażeniach bez zmiany stanu aplikacji.

Funkcje debugera:

  • Zapewniona jest bezpieczny: wykonywanie funkcja wewnętrzna debugger nie będzie uszkodzony proces, który jest debugowany.

  • W wyrażeniach są dozwolone wszystkie, nawet w scenariuszach, w których skutki uboczne i obliczanie wartości funkcji nie są dozwolone.

  • Praca w scenariuszach, w których wywołań funkcji regularne nie są możliwe, na przykład przy debugowaniu minizrzutu.

Funkcje debugera można również dokonać oceny wyrażenia wygodniejsze.Na przykład strncmp(str, “asd”) jest znacznie ułatwia pisanie w stanie przerwania niż str[0] == ‘a’ && str[1] == ‘s’ && str[2] == ‘d’. )

Obszar

Funkcje wewnętrzne

Długość ciągu

strlen, wcslen, strnlen, wcsnlen

Porównania ciągów

strcmp, wcscmp, stricmp, _stricmp, _strcmpi, wcsicmp, _wcscmpi, _wcsnicmp, strncmp, wcsncmp, strnicmp, wcsnicmp

Ciąg wyszukiwania

strchr, wcschr, strstr, wcsstr

Win32

GetLastError(), TlsGetValue()

Windows 8

WindowsGetStringLen(), WindowsGetStringRawBuffer()

Funkcje te wymagają proces, który jest debugowany będzie uruchomiona na Windows 8.Debugowania zrzutu pliki generowane z urządzenia systemu Windows 8 również wymaga, aby komputer Visual Studio systemem Windows 8.Jednakże jeśli są zdalne debugowanie urządzenia systemu Windows 8, Visual Studio komputerze może być uruchomiony system Windows 7.

Różne

__log2

Zwraca dziennika podstawa 2 określona liczba całkowita, zaokrąglone do najbliższej liczby całkowitej w dolnym.

Aby określić symbol za pomocą operatorów kontekstu

Operator kontekstu jest operator dodatkowe dostarczane przez macierzysty debugera.Podczas debugowania kodu macierzystego, można użyć operatora kontekstu do zakwalifikowania lokalizacji punkt przerwania, nazwa zmiennej lub wyrażenia.Operator kontekstu jest przydatne do celów takich jak określenie nazwy w zakresie zewnętrznym, w przeciwnym razie ukryte na skutek Nazwa lokalna.

Składnia

{,,[module] } expression

  • modulejest nazwą modułu.Można użyć pełnej ścieżki, aby odróżnić między modułami o tej samej nazwie.

  • expressiondowolne prawidłowe wyrażenie języka C++, która jest rozpoznawana jako prawidłowe miejsce docelowe nazwy funkcji, nazwa zmiennej lub adres wskaźnika w module.

Nawiasy klamrowe musi zawierać dwa przecinkami i moduł (wykonywalne lub biblioteki DLL) nazwa lub Pełna ścieżka.

Na przykład, aby ustawić punkt przerwania na SomeFunction funkcji EXAMPLE.dll:

{,,EXAMPLE.dll}SomeFunction

Jeśli module ścieżka zawiera przecinek, osadzony przestrzeń lub nawias, należy użyć ścieżki w cudzysłowie parser kontekstu prawidłowo rozpoznać ciąg.Znaki pojedynczego cudzysłowu są uważane za część nazwy pliku systemu Windows, należy używać podwójnych cudzysłowów.Na przykład:

{,"a long, long, library name.dll", } g_Var

Tester wyrażenie napotka symbol w wyrażeniach, wyszukuje symbol w następującej kolejności:

  1. Zakres leksykalny na zewnątrz, począwszy od bieżącego bloku, serii instrukcje zawarte w nawiasach i ustawicznego na zewnątrz z otaczającym bloku.Bieżący blok jest kod zawierający bieżącą lokalizację, adres wskaźnika instrukcji.

  2. Zakres funkcji.Bieżącą funkcję.

  3. Zakres klasy, jeśli bieżąca lokalizacja znajduje się wewnątrz funkcji składowej języka C++.Zakres klasy zawiera wszystkie klasy podstawowej.Tester wyrażenie używa reguł normalnej pozycji dominującej.

  4. Globalne symboli w bieżącego modułu.

  5. Publiczne symbole w bieżącym programie.

Z operatorem kontekstu Określ początkową moduł wyszukiwania i obwodnica bieżącej lokalizacji.

Ograniczenia dotyczące wyrażeń macierzystym C++

Po wprowadzeniu wyrażenia języka C/C++ w oknie Debuger stosuje się ograniczenia te ogólne:

Kontrola dostępu

Debugera można uzyskać dostęp do wszystkich członków klasy niezależnie od kontroli dostępu.Można sprawdzić każdy członek obiektu klasy, w tym podstawowych klas i obiektów osadzonych.

Niejednoznacznych odwołań

Jeśli wyrażenie debugera odnosi się do nazwa członka niejednoznaczne, należy użyć nazwy klasy Aby zakwalifikować go.Na przykład jeśli CObject jest wystąpieniem CClass, która dziedziczy funkcji element członkowski o nazwie expense z obu AClass i BClass, CObject.expense jest niejednoznaczny.Można rozwiązać niejednoznaczności podobny do tego:

CObject.BClass::expense

Aby rozwiązać niejasności, szacującego stosuje reguły normalnej pozycji dominującej dotyczących nazwy składników.

Anonimowe przestrzenie nazw

Tester wyrażenie macierzystym C++ nie obsługuje anonimowe przestrzenie nazw.Załóżmy, na przykład, następujący kod:

#include "stdafx.h"

namespace mars 
{ 
    namespace
    {
        int test = 0; 
    } 

} 


int main() 
{ 
    // Adding a watch on test does not work. 
    mars::test++; 
    return 0; 
} 

Jedynym sposobem, aby obejrzeć symbol test w tym przykładzie jest użycie dekoracyjną nazwę:

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

Konstruktory, destruktory i konwersje

Nie można wywołać konstruktora lub destruktora w przypadku obiektu jawnie lub niejawnie za pomocą wyrażenia, który wzywa do budowy obiektów tymczasowych.Na przykład następujące wyrażenie jawnie wywołuje konstruktor i powoduje wyświetlenie komunikatu o błędzie:

Date( 2, 3, 1985 )

Nie można wywołać funkcji konwersji, jeżeli miejsce przeznaczenia konwersji jest klasą.Takie przekształcenie polega na budowę obiektu.Na przykład jeśli myFraction jest wystąpieniem CFraction, która definiuje operator funkcji konwersji FixedPoint, następujące wyrażenie powoduje błąd:

(FixedPoint)myFraction

Jednak jeśli miejscem docelowym konwersji jest typem wbudowanym mogą wywoływać funkcję konwersji.Jeśli CFraction definiuje funkcję konwersji operator float, poniższe wyrażenie jest dozwolony w debugerze:

(float)myFraction

Można wywołać funkcje, które zwracają obiekt lub zadeklarować obiekty lokalne.

Nie można wywołać funkcji new lub delete operatorów.Następujące wyrażenie nie działa w debugerze:

new Date(2,3,1985)

Dziedziczenie

Debuger umożliwia wyświetlanie klasy obiekt, który posiada wirtualnych klas bazowych, Członkowie wirtualnego klasy podstawowej są wyświetlane dla każdej ścieżki dziedziczenia, nawet jeśli tylko jedno wystąpienie tych członków jest przechowywany.

Wywołania funkcji wirtualnych są poprawnie obsługiwane przez tester wyrażenie.Załóżmy na przykład, klasa CEmployee definiuje funkcję wirtualnych computePay, który jest ponownie zdefiniować w klasie, która dziedziczy z CEmployee.Można wywołać computePay za pomocą wskaźnika do CEmployee i właściwego funkcji wykonywane:

empPtr->computePay()

Wskaźnik do obiektu klasy pochodnej można rzutować na wskaźnik do obiektu klasy podstawowej.Wskaźnik do obiektu klasy podstawowej można rzutować na wskaźnik do obiektu klasy pochodne z wyjątkiem gdy dziedziczenie jest wirtualna.

Funkcje wewnętrzne Wplatany i kompilatora

Wyrażenie debuger nie można wywołać kompilator funkcji wewnętrznych lub inlined działa, jeśli funkcja pojawi się co najmniej raz w normalnej funkcji.

Stałe numeryczne

Stałe będące liczbami całkowitymi można użyć wyrażenia debugera w formacie ósemkową, szesnastkową lub dziesiętną.Domyślnie narzędzie debugger oczekuje decimal stałych.To ustawienie można zmienić na Ogólne strony Debugowanie kartę.

Symbole prefiks lub sufiks, który służy do wyświetlania liczb w innej bazy.W poniższej tabeli przedstawiono formularzy, których można użyć.

Składnia

Przykład (dziesiętną 100)

Podstawy

digits

100 lub 64

Dziesiętną lub szesnastkową, w zależności od bieżącego ustawienia.

0digits

0144

Octal (podstawa 8)

0ndigits

0n100

Dziesiętny (podstawa 10)

0xdigits

0x64

Szesnastkowy (podstawa 16)

digitsh

64h

Szesnastkowy (podstawa 16)

Operator funkcji

Wyrażenie debugera mogą wywoływać funkcje operatora dla klasy, jawnie lub niejawnie.Załóżmy na przykład, myFraction i yourFraction są instancjami klasy, która definiuje operator+.Można wyświetlić sumy tych dwóch obiektów za pomocą następującego wyrażenia:

myFraction + yourFraction

Jeśli funkcję operatora jest zdefiniowana jako znajomego, można wywołać ją niejawnie przy użyciu tej samej składni, jak w przypadku funkcji członka, lub można go wywołać, jawnie, w następujący sposób:

operator+( myFraction, yourFraction )

Jak zwykłych funkcji z argumentów, które wymagają konwersji, obejmujących budowa obiektu nie można wywołać funkcji operatora.

Debuger nie obsługuje przeciążonych operatorów z wersji const i innych niż stała.Przeciążone operatory const i const innych niż wersje są często używane w bibliotekę STL.

Przeciążenie

Wyrażenie debuger może wywołać funkcji zastąpionej, jeśli istnieje dokładne dopasowanie lub dopasowania nie wymaga konwersji dotyczące obiektów budowlanych.Na przykład jeśli calc funkcja ma CFraction obiektu jako parametr i CFraction klasa definiuje konstruktora pojedynczy argument, który akceptuje całkowitą następujące wyrażenie powoduje błąd:

calc( 23 )

Mimo że istnieje prawne konwersji do konwersji wartości całkowitej do CFraction obiekt, który calc oczekuje, takie przeliczenie utworzenie obiektu i nie jest obsługiwana.

Pierwszeństwo

W wyrażeniach debugera, C++ zakresu operatora (::) ma niższy priorytet niż ma to miejsce w kodzie źródłowym.W kodzie źródłowym języka C++ Ten operator ma najwyższy priorytet.W debugerze, pierwszeństwo przed przypada między base i przyrostkowe operatory (->, ++, --) i operatory jednoargumentowe (!, &, *i innych).

Formaty symbol

Wprowadź wyrażenie debugera, który zawiera symbole w tej samej formie używane w kodzie źródłowym, pod warunkiem że są symbole w module skompilowany z informacje debugowania pełnego (/Zi lub /ZI).Jeśli wprowadzisz wyrażenie, które zawiera symbole publiczne, które symbole znajdują się w bibliotekach lub w modułach skompilowany z /Zd, należy użyć dekoracyjną nazwę symbolu, formularz używany w kod obiektu.Aby uzyskać więcej informacji, zobacz /Z7, /Zd, /Zi, /ZI (format informacji o debugowaniu).

Znajduje się lista wszystkich nazw można uzyskać z dekoracyjną i bez dekoracji formularzy przy użyciu opcji/LINK map.Aby uzyskać więcej informacji, zobacz /map (Generowanie argument Mapfile).

Przekręcenie nazwy jest mechanizm używany w celu wymuszenia powiązania typu palety.Oznacza to, że tylko nazwy i odwołania z dokładnie pasujące pisowni, sprawy, konwencja wywołania i typ są ze sobą powiązane.

Nazwy zadeklarowanych za pomocą C konwencji wywoływania, pośrednio lub bezpośrednio za pomocą _cdecl słowo kluczowe, które zaczynają się od podkreślenia ( _ ).Na przykład funkcja main mogą być wyświetlane jako _main.Nazwy zadeklarowany jako _fastcall zaczyna się od @ symbol.

Dla języka C++ nazwę dekoracyjną koduje typ symbolu oprócz konwencję wywołania.Ten formularz nazwy może być długi i trudny do czytania.Nazwa zaczyna się od co najmniej jeden znak zapytania (?).Dla funkcji języka C++ dekoracji zawiera zakres funkcji, typy parametrów funkcji i zwracany typ funkcji.

Typ rzutowania

Jeśli można rzutować na typ, typ musi być znana z debugera.Musisz mieć inny obiekt tego typu w programie.Typy utworzone za pomocą typedef instrukcje nie są obsługiwane.