Windows 코딩 규칙
Windows 프로그래밍을 처음 접하는 경우 Windows 프로그램을 처음 볼 때 당황스러울 수 있습니다. 코드는 DWORD_PTR 및 LPRECT와 같은 이상한 형식 정의로 채워져 있으며 변수에는 hWnd 및 pwsz(헝가리언 표기법이라고 함)와 같은 이름이 있습니다. Windows 코딩 규칙 중 일부를 배우는 것은 시간을 할애할 만한 가치가 있습니다.
대부분의 Windows API는 함수 또는 COM(구성 요소 개체 모델) 인터페이스로 구성됩니다. C++ 클래스로 제공되는 Windows API는 거의 없습니다. (주목할 만한 예외는 2차원 그래픽 API 중 하나인 GDI+입니다.)
Typedefs
Windows 헤더에는 많은 typedef가 포함되어 있습니다. 이들 중 대부분은 헤더 파일 WinDef.h에 정의되어 있습니다. 다음은 자주 보게 되는 몇 가지 항목입니다.
정수 형식
데이터 형식 | 크기 | 부호 여부 |
---|---|---|
BYTE | 8비트 | 부호 없음 |
DWORD | 32비트 | 부호 없음 |
INT32 | 32비트 | 서명 |
INT64 | 64비트 | 서명 |
LONG | 32비트 | 서명 |
LONGLONG | 64비트 | 서명 |
UINT32 | 32비트 | 부호 없음 |
UINT64 | 64비트 | 부호 없음 |
ULONG | 32비트 | 부호 없음 |
ULONGLONG | 64비트 | 부호 없음 |
WORD | 16비트 | 부호 없음 |
보다시피 이러한 typedef는 어느 정도 중복됩니다. 이러한 중복의 일부는 단순히 Windows API의 역사 때문입니다. 여기에 나열된 형식의 크기는 고정되어 있으며 크기는 32비트와 64비트 애플리케이션 모두에서 동일합니다. 예를 들어 DWORD 형식은 항상 32비트 크기입니다.
부울 형식
BOOL은 C++의 bool과 구별되는 int의 형식 별칭이며 부울 값을 나타내는 다른 형식과 다릅니다. 헤더 파일 WinDef.h
은 또한 BOOL과 함께 사용할 두 개의 값을 정의합니다.
#define FALSE 0
#define TRUE 1
그러나 이러한 TRUE 정의에도 불구하고 BOOL 형식을 반환하는 대부분의 함수는 부울 참을 나타내기 위해 0이 아닌 값을 반환할 수 있습니다. 따라서 항상 다음을 작성해야 합니다.
// Right way.
if (SomeFunctionThatReturnsBoolean())
{
...
}
// or
if (SomeFunctionThatReturnsBoolean() != FALSE)
{
...
}
그리고 다음은 아닙니다.
if (result == TRUE) // Wrong!
{
...
}
BOOL은 정수 유형이며 C++의 bool과 교환할 수 없습니다.
포인터 형식
Windows는 pointer-to-X 형식의 많은 데이터 형식을 정의합니다. 일반적으로 이름에 접두사 P- 또는 LP-가 있습니다. 예를 들어 LPRECT는 RECT에 대한 포인터이며 여기서 RECT는 사각형을 설명하는 구조체입니다. 다음 변수 선언은 동일합니다.
RECT* rect; // Pointer to a RECT structure.
LPRECT rect; // The same
PRECT rect; // Also the same.
16비트 아키텍처(16비트 Windows)에는 2가지 유형의 포인터가 있습니다. P는 “포인터”를 나타내고 LP는 “긴 포인터”를 나타냅니다. 현재 세그먼트 외부의 메모리 범위를 주소 지정하려면 긴 포인터(먼 포인터라고도 함)가 필요했습니다. 16비트 코드를 32비트 Windows로 더 쉽게 포팅할 수 있도록 LP 접두사가 보존되었습니다. 현재는 구별되지 않으며 이러한 포인터 형식은 모두 동일합니다. 이러한 접두사를 사용하지 마세요. 반드시 사용해야 하는 경우 P를 사용하세요.
포인터 정밀도 형식
다음 데이터 형식은 항상 포인터의 크기입니다. 즉, 32비트 애플리케이션에서는 크기가 32비트이고 64비트 애플리케이션에서는 64비트입니다. 크기는 컴파일 시간에 결정됩니다. 32비트 애플리케이션이 64비트 Windows에서 실행되는 경우 이러한 데이터 형식은 여전히 4바이트 크기입니다. (64비트 애플리케이션은 32비트 Windows에서 실행할 수 없으므로 그 반대의 상황은 발생하지 않습니다.)
- DWORD_PTR
- INT_PTR
- LONG_PTR
- ULONG_PTR
- UINT_PTR
이러한 형식은 정수가 포인터로 캐스팅될 수 있는 경우에 사용됩니다. 또한 포인터 산술에 대한 변수와 메모리 버퍼의 전체 바이트 범위를 반복하는 루프 카운터를 정의하는 데 사용됩니다. 더 일반적으로는 기존 32비트 값이 64비트 Windows에서 64비트로 확장된 위치에 표시됩니다.
헝가리언 표기법
헝가리언 표기법은 변수에 대한 추가 정보를 제공하기 위해 변수 이름에 접두어를 추가하는 방법입니다. (표기법의 발명가인 Charles Simonyi가 헝가리인이었기 때문에 그 이름이 붙여졌습니다).
원래 형식에서 헝가리언 표기법은 변수에 대한 의미론적 정보를 제공하여 의도한 용도를 알려 줍니다. 예를 들어 i는 인덱스를 의미하고 cb는 바이트 크기(“바이트 수”)를 의미하며 rw와 col은 행과 열 번호를 의미합니다. 이러한 접두사는 잘못된 컨텍스트에서 변수를 실수로 사용하지 않도록 설계되었습니다. 예를 들어 rwPosition + cbTable
표현식을 본다면 행 번호가 크기에 추가되고 있음을 알 수 있으며 이는 코드의 버그임이 거의 확실합니다.
더 일반적인 형식의 헝가리언 표기법은 접두사를 사용하여 형식 정보(예: DWORD의 경우 dw, WORD의 경우 w)를 제공합니다.
참고
C++ 핵심 지침에서는 접두사 표기법(예: 헝가리언 표기법)을 권장하지 않습니다. NL.5: 이름에 형식 정보를 인코딩하지 마세요를 참조하세요. 내부적으로 Windows 팀은 더 이상 이를 사용하지 않습니다. 그러나 샘플과 설명서에 사용된 경우가 남아있습니다.