Platform SDK: Win64 Programming Preview |
[This is preliminary documentation and subject to change.]
When porting your 32-bit code to 64-bit code, consider the following points:
#ifdef _WIN32 // Win32 code ... #else // Win16 code ... #endif
However, the 64-bit compiler defines _WIN32 for backward compatibility.
#ifdef _WIN16 // Win16 code ... #else // Win32 code ... #endif
In this case, the else clause can represent _WIN32 or _WIN64.
TYPE_ALIGNMENT( KFLOATING_SAVE ) == 4 on x86, 8 on IA-64 TYPE_ALIGNMENT( UCHAR ) == 1 everywhere
As an example, kernel code that currently looks like this:
ProbeForRead( UserBuffer, UserBufferLength, sizeof(ULONG) );
should probably be changed to:
ProbeForRead( UserBuffer, UserBufferLength, TYPE_ALIGNMENT(IOCTL_STRUC) );
The current plan is to not turn on automatic fixes of kernel-mode alignment exceptions for 64-bit systems, as they are currently for 32-bit systems.
UINT_PTR a; ULONG b; a = a & ~(b - 1);
The problem is that ~(b–1) produces 0x0000 0000 xxxx xxxx and not 0xFFFF FFFF xxxx xxxx. The compiler will not detect this. To fix this, change the code as follows:
a = a & ~((UINT_PTR)b - 1);
LONG a; ULONG b; LONG c; a = -10 b = 2; c = a / b;
The result is unexpectedly large. The rule is that if either operand is unsigned, the result is unsigned. In the preceding example, a
is converted to a signed value and stored in c
. Both conversions involve no numeric manipulation.
As another example, consider the following:
ULONG x; LONG y; LONG *pVar1; LONG *pVar2; pVar2 = pVar1 + y * (x - 1);
The problem arises because x
is unsigned, which makes the entire expression unsigned. This works fine unless y
is negative. In this case, y
is converted to an unsigned value, the expression is evaluated using 32-bit precision, scaled, and added to pVar1
. A 32-bit unsigned negative number becomes a large 64-bit positive number, which gives the wrong result. To fix this problem, declare x
as a signed value or explicitly typecast it to LONG in the expression.
struct xx { DWORD NumberOfPointers; PVOID Pointers[1]; };
The following code is wrong because the compiler will pad the structure with an additional 4 bytes to make the 8-byte alignment:
malloc(sizeof(DWORD)+100*sizeof(PVOID));
The following code is correct:
malloc(offsetof(struct xx, Pointers) +100*sizeof(PVOID));