네이티브 C++의 식
디버거는 Microsoft 및 ANSI C/C++ 식을 대부분 받아들입니다. 디버거는 내장 함수와 컨텍스트 연산자도 제공하여 더욱 안전하고 간편하게 식을 계산할 수 있도록 합니다. 이 항목에서는 다음에 유의해야 하는 C++ 식의 제한 사항에 대해 설명합니다.
코드, 스크립트 또는 관리 코드 식에는 컨텍스트 연산자나 대부분의 형식 지정자를 사용할 수 없습니다. 컨텍스트 연산자와 형식 지정자는 네이티브 C++ 식 계산기에서만 인식됩니다.
이 단원의 내용
디버거 내장 함수를 사용하여 상태 유지
컨텍스트 연산자를 사용하여 기호 지정
네이티브 C++ 식의 제한 사항
액세스 제어
모호한 참조
익명 네임스페이스
생성자, 소멸자 및 변환
상속
인라인 및 컴파일러 내장 함수
숫자 상수
연산자 함수
오버로딩
우선 순위
기호 형식
형식 캐스팅
디버거 내장 함수를 사용하여 상태 유지
디버거 내장 함수는 응용 프로그램의 상태를 변경하지 않고 식에서 특정 C/C++ 함수를 호출하는 방법을 제공합니다.
디버거 내장 함수의 특징은 다음과 같습니다.
안전이 보장됩니다. 디버거 내장 함수를 실행하는 경우 디버깅 중인 프로세스가 손상되지 않습니다.
모든 식에서 허용됩니다. 파생 작업과 함수 실행이 허용되지 않는 시나리오에서도 허용됩니다.
미니덤프 디버깅과 같이 일반 함수 호출이 가능하지 않은 시나리오에서 작동합니다.
디버거 내장 함수를 사용하면 식 계산도 보다 편리해질 수 있습니다. 예를 들어 strncmp(str, “asd”)는 str[0] == ‘a’ && str[1] == ‘s’ && str[2] == ‘d’보다 중단점 조건에서 작성하기가 훨씬 쉽습니다. )
영역 |
내장 함수 |
---|---|
문자열 길이 |
strlen, wcslen, strnlen, wcsnlen |
문자열 비교 |
strcmp, wcscmp, stricmp, _stricmp, _strcmpi, wcsicmp, _wcscmpi, _wcsnicmp, strncmp, wcsncmp, strnicmp, wcsnicmp |
문자열 검색 |
strchr, wcschr, strstr, wcsstr |
Win32 |
GetLastError(), TlsGetValue() |
Windows 8 |
WindowsGetStringLen(), WindowsGetStringRawBuffer() 이러한 함수를 사용하려면 디버깅 중인 프로세스가 Windows 8에서 실행되어야 합니다. Windows 8 장치에서 생성된 덤프 파일을 디버깅하려면 Visual Studio 컴퓨터에서 Windows 8이 실행되어야 합니다. 그러나 Windows 8 장치를 원격으로 디버깅하는 경우에는 Visual Studio 컴퓨터에서 Windows 7이 실행될 수 있습니다. |
기타 |
__log2 가장 가까운 낮은 정수로 반올림된 밑이 2인 지정된 정수의 로그 값을 반환합니다. |
컨텍스트 연산자를 사용하여 기호 지정
컨텍스트 연산자는 네이티브 디버거에서 추가로 제공하는 연산자입니다. 네이티브 코드를 디버깅할 때 컨텍스트 연산자를 사용하여 중단점 위치, 변수 이름 또는 식을 한정할 수 있습니다. 컨텍스트 연산자는 로컬 이름에 의해 숨겨진 외부 범위에서 이름을 지정하는 등의 경우에 유용합니다.
구문
{,,[module] } expression
module은 모듈의 이름입니다. 이름이 같은 여러 모듈을 구분하기 위해 전체 경로를 사용할 수 있습니다.
expression은 module의 함수 이름, 변수 이름 또는 포인터 주소와 같은 올바른 대상으로 확인되는 모든 유효한 C++ 식입니다.
중괄호에는 쉼표 두 개와 모듈(실행 파일 또는 DLL) 이름 또는 전체 경로가 포함되어야 합니다.
예를 들어 EXAMPLE.dll의 SomeFunction 함수에 중단점을 설정하려는 경우는 다음과 같습니다.
{,,EXAMPLE.dll}SomeFunction
module 경로에 쉼표, 공백 또는 중괄호가 포함되어 있으면 컨텍스트 파서가 문자열을 적절하게 인식할 수 있도록 경로에 큰따옴표를 사용해야 합니다. 작은따옴표는 Windows 파일 이름의 일부로 간주되므로 큰따옴표를 사용해야 합니다. 예를 들면 다음과 같습니다.
{,"a long, long, library name.dll", } g_Var
식 계산기는 식에서 기호가 나오면 다음과 같은 순서로 기호를 검색합니다.
현재 블록(중괄호에 포함된 일련의 문)에서 시작하여 바깥쪽 블록의 외부로 계속되는 바깥쪽 어휘 범위. 현재 블록은 현재 위치(명령 포인터 주소)가 포함된 코드입니다.
함수 범위. 현재 함수입니다.
현재 위치가 C++ 멤버 함수 내부인 경우 클래스 범위. 클래스 범위에는 모든 기본 클래스가 포함됩니다. 식 계산기는 일반 우위 규칙을 사용합니다.
현재 모듈의 전역 기호
현재 프로그램의 공용 기호
컨텍스트 연산자를 사용하여 검색의 시작 모듈을 지정하고 현재 위치를 무시할 수 있습니다.
네이티브 C++ 식의 제한 사항
디버거 창에 C/C++ 식을 입력하는 경우 다음과 같은 일반적인 제한 사항이 적용됩니다.
액세스 제어
디버거는 액세스 제어에 관계없이 모든 클래스 멤버에 액세스할 수 있습니다. 따라서 기본 클래스와 포함된 멤버 개체를 비롯한 모든 클래스 개체 멤버를 검사할 수 있습니다.
모호한 참조
디버거 식이 모호한 멤버 이름을 참조하는 경우 클래스 이름을 사용하여 한정해야 합니다. 예를 들어 CObject가 AClass 및 BClass에서 expense라는 멤버 함수를 상속하는 CClass의 인스턴스이면 CObject.expense는 모호한 참조입니다. 다음과 같은 방법으로 모호성을 해결할 수 있습니다.
CObject.BClass::expense
모호성을 해결하기 위해 식 계산기는 멤버 이름과 관련된 일반 우위 규칙을 적용합니다.
익명 네임스페이스
네이티브 C++ 식 계산기는 익명 네임스페이스를 지원하지 않습니다. 예를 들어 다음과 같은 코드가 있다고 가정합니다.
#include "stdafx.h"
namespace mars
{
namespace
{
int test = 0;
}
}
int main()
{
// Adding a watch on test does not work.
mars::test++;
return 0;
}
이 예제에서 test 기호를 조사하는 유일한 방법은 데코레이팅된 이름을 사용하는 것입니다.
(int*)?test@?A0xccd06570@mars@@3HA
생성자, 소멸자 및 변환
임시 개체 생성을 호출하는 식을 사용하여 명시적으로나 암시적으로 개체에 대한 생성자나 소멸자를 호출할 수 없습니다. 예를 들어 다음 식을 사용하여 명시적으로 생성자를 호출하면 오류 메시지가 나타납니다.
Date( 2, 3, 1985 )
클래스로 변환하는 경우에는 변환 함수를 호출할 수 없습니다. 이러한 변환에는 개체 생성이 포함됩니다. 예를 들어 myFraction이 변환 함수 연산자 FixedPoint를 정의하는 CFraction의 인스턴스인 경우에 다음 식을 사용하면 오류가 발생합니다.
(FixedPoint)myFraction
그러나 기본 제공 형식으로 변환하는 경우에는 변환 함수를 호출할 수 있습니다. CFraction이 변환 함수 operator float를 정의하는 경우 디버거에서 다음 식을 사용할 수 있습니다.
(float)myFraction
개체를 반환하거나 지역 개체를 선언하는 함수를 호출할 수 있습니다.
new 또는 delete 연산자를 호출할 수 없습니다. 다음 식은 디버거에서 작동하지 않습니다.
new Date(2,3,1985)
상속
디버거를 사용하여 가상 기본 클래스가 있는 클래스 개체를 표시하는 경우, 각 상속 경로마다 가상 기본 클래스의 멤버가 표시됩니다. 그러나 이러한 멤버의 인스턴스는 하나만 저장됩니다.
가상 함수 호출은 식 계산기에서 적절하게 처리됩니다. 예를 들어 CEmployee 클래스에서 가상 함수 computePay가 정의되고 이 함수가 CEmployee에서 상속하는 클래스에서 다시 정의되는 경우, CEmployee에 대한 포인터를 통해 computePay를 호출하여 적절한 함수를 실행할 수 있습니다.
empPtr->computePay()
파생된 클래스 개체에 대한 포인터를 기본 클래스 개체에 대한 포인터로 캐스팅할 수 있으며, 상속이 가상인 경우를 제외하고 기본 클래스 개체에 대한 포인터를 파생된 클래스 개체에 대한 포인터로 캐스팅할 수 있습니다.
인라인 및 컴파일러 내장 함수
디버거 식에서는 일반 함수로 한 번 이상 나타나지 않는 한 컴파일러 내장 함수나 인라인 함수를 호출할 수 없습니다.
숫자 상수
디버거 식에서는 8진수, 16진수 또는 10진수 형식의 정수 상수를 사용할 수 있습니다. 기본적으로 디버거는 10진수 상수를 사용하도록 설정됩니다. 이 설정은 디버깅 탭의 일반 페이지에서 변경할 수 있습니다.
접두 또는 접미 기호를 사용하여 다른 형식의 숫자를 나타낼 수 있습니다. 다음 표에서는 사용할 수 있는 형태를 보여 줍니다.
구문 |
예제(10진수 100) |
Base |
---|---|---|
digits |
100 또는 64 |
현재 설정에 따라 10진수 또는 16진수 |
0 digits |
0144 |
8진수 |
0n digits |
0n100 |
10진수 |
0x digits |
0x64 |
16진수 |
digits h |
64h |
16진수 |
연산자 함수
디버거 식에서는 암시적으로나 명시적으로 클래스에 대한 연산자 함수를 호출할 수 있습니다. 예를 들어 myFraction 및 yourFraction이 operator+를 정의하는 클래스의 인스턴스인 경우, 다음 식을 사용하여 이러한 두 개체의 합을 표시할 수 있습니다.
myFraction + yourFraction
연산자 함수가 friend로 정의된 경우, 멤버 함수에 대한 구문과 동일한 구문을 사용하여 암시적으로 호출할 수도 있고 다음과 같이 명시적으로 호출할 수도 있습니다.
operator+( myFraction, yourFraction )
일반 함수와 마찬가지로 연산자 함수는 개체 생성을 포함한 변환이 필요한 인수를 사용하여 호출할 수 없습니다.
디버거는 const 및 비 const 버전이 있는 오버로드된 연산자를 지원하지 않습니다. const 및 비 const 버전이 있는 오버로드된 연산자는 표준 템플릿 라이브러리에 자주 사용됩니다.
오버로드
함수가 정확하게 일치하거나 개체 생성을 포함한 변환을 하지 않고도 일치하는 경우에는 디버거 식에서 오버로드된 함수를 호출할 수 있습니다. 예를 들어 calc 함수에서 CFraction 개체를 매개 변수로 사용하고 CFraction 클래스가 정수를 받아들이는 단일 인수 생성자를 정의하는 경우, 다음 식을 사용하면 오류가 발생합니다.
calc( 23 )
calc에 적합한 CFraction 개체로 정수를 변환하는 올바른 변환이 있더라도 이러한 변환은 개체 생성을 포함하므로 지원되지 않습니다.
우선 순위
디버거 식에 있는 C++ 범위 연산자(::)는 소스 코드에 있는 경우보다 우선 순위가 낮습니다. C++ 소스 코드에서는 이 연산자의 우선 순위가 가장 높습니다. 디버거에서 이 연산자의 우선 순위는 기본 및 후위 연산자(->, ++, --)와 단항 연산자(!, &, * 등) 사이에 속합니다.
기호 형식
전체 디버그 정보(/Zi 또는 /ZI)를 사용하여 컴파일된 모듈에 기호가 있으면 소스 코드에 사용된 동일한 형태의 기호를 포함하는 디버거 식을 입력합니다. /Zd를 사용하여 컴파일된 모듈이나 라이브러리에 있는 기호인 공용 기호가 포함된 식을 입력하는 경우에는 개체 코드에서 사용되는 형태의 데코레이팅된 기호 이름을 사용해야 합니다. 자세한 내용은 /Z7, /Zd, /Zi, /ZI(디버깅 정보 형식)를 참조하십시오.
LINK /MAP 옵션을 사용하면 데코레이팅된 형태와 데코레이팅되지 않은 형태의 모든 이름 목록을 얻을 수 있습니다. 자세한 내용은 /MAP(맵 파일 생성)을 참조하십시오.
이름 데코레이션은 형식이 안전한 링크를 적용하는 데 사용하는 메커니즘입니다. 즉, 철자, 대/소문자, 호출 규칙 및 형식이 정확하게 일치하는 이름과 참조만 서로 링크됩니다.
_cdecl 키워드를 사용하여 암시적으로나 명시적으로 C 호출 규칙을 사용하여 선언된 이름은 밑줄(_)로 시작합니다. 예를 들어 main 함수는 _main으로 표시될 수 있습니다. _fastcall로 선언된 이름은 @ 기호로 시작합니다.
C++에서 데코레이팅된 이름은 호출 규칙 외에 기호의 형식을 인코딩합니다. 이러한 형태의 이름은 길고 읽기 어려울 수 있습니다. 이름은 하나 이상의 물음표(?)로 시작합니다. C++ 함수의 데코레이션에는 함수 범위, 함수 매개 변수의 형식 및 함수 반환 형식이 포함됩니다.
형식 캐스팅
형식으로 캐스팅하는 경우 해당 형식이 디버거에 알려져야 합니다. 프로그램에 해당 형식의 또 다른 개체가 있어야 합니다. typedef 문을 사용하여 만든 형식은 지원되지 않습니다.