기타 고려 사항
코드를 포팅할 때 다음 사항을 고려합니다.
다음 가정은 더 이상 유효하지 않습니다.
#ifdef _WIN32 // Win32 code ... #else // Win16 code ... #endif
그러나 64비트 컴파일러는 이전 버전과의 호환성을 위해 _WIN32 정의합니다.
다음 가정은 더 이상 유효하지 않습니다.
#ifdef _WIN16 // Win16 code ... #else // Win32 code ... #endif
이 경우 else 절은 _WIN32 또는 _WIN64 나타낼 수 있습니다.
데이터 형식 맞춤에 주의하세요. TYPE_ALIGNMENT 매크로는 데이터 형식의 맞춤 요구 사항을 반환합니다. 예:
TYPE_ALIGNMENT( KFLOATING_SAVE )
== x86의 경우 4, Intel Itanium 프로세서TYPE_ALIGNMENT( UCHAR )
의 경우 8 = 1예를 들어 현재 다음과 같은 커널 코드가 있습니다.
ProbeForRead( UserBuffer, UserBufferLength, sizeof(ULONG) );
는 다음으로 변경될 수 있습니다.
ProbeForRead( UserBuffer, UserBufferLength, TYPE_ALIGNMENT(IOCTL_STRUC) );
커널 모드 맞춤 예외의 자동 수정은 Intel Itanium 시스템에 대해 사용하지 않도록 설정됩니다.
NOT 작업에 주의하세요. 다음을 살펴보세요.
UINT_PTR a; ULONG b; a = a & ~(b - 1);
문제는 ~(b-1)가 "0xFFFF FFFF xxxx xxxx"가 아닌 "0x0000 xxxx xxxx"를 생성한다는 것입니다. 컴파일러에서 이를 검색하지 않습니다. 이 문제를 해결하려면 다음과 같이 코드를 변경합니다.
a = a & ~((UINT_PTR)b - 1);
서명되지 않은 작업과 서명되지 않은 작업을 신중하게 수행합니다. 다음을 살펴보세요.
LONG a; ULONG b; LONG c; a = -10; b = 2; c = a / b;
예기치 않게 큰 결과입니다. 규칙은 피연산자 중 하나가 서명되지 않은 경우 결과가 서명되지 않은 것입니다. 앞의 예제에서 은 부호 없는 값으로 변환되고 b로 나뉘고 결과는 c에 저장됩니다. 변환에는 숫자 조작이 포함되지 않습니다.
또 다른 예로 다음을 고려합니다.
ULONG x; LONG y; LONG *pVar1; LONG *pVar2; pVar2 = pVar1 + y * (x - 1);
x가 서명되지 않아 전체 식이 서명되지 않아 문제가 발생합니다. 이는 y가 음수가 아닌 한 잘 작동합니다. 이 경우 y는 부호 없는 값으로 변환되고, 식은 32비트 정밀도를 사용하여 계산되고, 크기를 조정하고, pVar1에 추가됩니다. 부호 없는 32비트 음수는 큰 64비트 양의 숫자가 되어 잘못된 결과를 제공합니다. 이 문제를 해결하려면 x를 서명된 값으로 선언하거나 식에서 명시적으로 LONG 에 형식을 지정합니다.
증분 크기 할당을 만들 때는 주의해야 합니다. 예:
struct xx { DWORD NumberOfPointers; PVOID Pointers[100]; };
컴파일러가 8바이트 맞춤을 만들기 위해 구조체를 4바이트 더 패딩하기 때문에 다음 코드가 잘못되었습니다.
malloc(sizeof(DWORD) + 100*sizeof(PVOID));
다음 코드가 정확합니다.
malloc(offsetof(struct xx, Pointers) + 100*sizeof(PVOID));
CreateFileMapping과 같은 함수에는 전달
(HANDLE)0xFFFFFFFF
하지 마세요. 대신 INVALID_HANDLE_VALUE 사용합니다.문자열을 인쇄할 때 적절한 형식 지정자를 사용합니다. %p를 사용하여 포인터를 16진수로 인쇄합니다. 포인터를 인쇄하는 데 가장 적합한 선택입니다. Microsoft Visual C++ %I를 지원하여 다형 데이터를 인쇄합니다. 또한 Visual C++는 %I64를 지원하여 64비트인 값을 인쇄합니다.