Some examples of the 64-bit code errors

22
Some examples of the 64-bit code errors Author: Evgeniy Ryzhkov Date: 23.07.2007 Abstract While porting 32-bit software to 64-bit systems there may appear some errors in the code of applications which were written in C++ language. The cause for these hides in the alteration of the base data types (to be more exact, in the relations between them) with the new hardware platform. This article contains various examples of 64-bit errors. However, we have learnt much more examples and types of errors since we started writing the article and they were not included into it. Please see the article "A Collection of Examples of 64-bit Errors in Real Programs " that covers defects in 64-bit programs we know of most thoroughly. We also recommend you to study the course "Lessons on development of 64-bit C/C++ applications " where we describe the methodology of creating correct 64- bit code and searching for all types of defects using the Viva64 code analyzer. Introduction While porting 32-bit software to 64-bit systems there may appear some errors in the code of applications which were written in C++ language. The cause for these hides in the alteration of the base data types (to be more exact, in the relations between them) with the new hardware platform. "But isn't C++ a high-level language!" you may ask, and you will be right. But still all the high-level abstractions are realized through the low-level data types. Help documentation for developers is sure to contain the description of such errors. However, even such authoritative sources as, for example MSDN, often give only platitudes, for instance: int and long remained 32-bit ones with 64-bit versions of Widows; size_t, time_t, and ptrdiff_t became 64-bit ones with 64-bit versions of Windows. But what does it mean for a developer and what problems may it potentially cause - all this is not reported in the help. Meanwhile, there are very few articles which contain certain examples of application code errors in 64- bit Windows versions. This article is to fill the vacuum. First of all some terminology. Memsize type is any data type which changes its size when the digit capacity of architecture is changed from 32 bits to 64 bits. The examples are size_t, ptrdiff_t, DWORD_PTR, LONG_PTR and others. Take a note that only short examples of errors are given in the article. The explanation of their causes are given in the article "20 issues of porting C++ of porting C++ code on the 64-bit platform" http://www.viva64.com/art-1-2-599168895.html .

description

While porting 32-bit software to 64-bit systems there may appear some errors in the code of applications which were written in C++ language. The cause for these hides in the alteration of the base data types (to be more exact, in the relations between them) with the new hardware platform.

Transcript of Some examples of the 64-bit code errors

Page 1: Some examples of the 64-bit code errors

Some examples of the 64-bit code errors

Author: Evgeniy Ryzhkov

Date: 23.07.2007

Abstract While porting 32-bit software to 64-bit systems there may appear some errors in the code of

applications which were written in C++ language. The cause for these hides in the alteration of the base

data types (to be more exact, in the relations between them) with the new hardware platform.

This article contains various examples of 64-bit errors. However, we have learnt much more examples

and types of errors since we started writing the article and they were not included into it. Please see the

article "A Collection of Examples of 64-bit Errors in Real Programs" that covers defects in 64-bit

programs we know of most thoroughly. We also recommend you to study the course "Lessons on

development of 64-bit C/C++ applications" where we describe the methodology of creating correct 64-

bit code and searching for all types of defects using the Viva64 code analyzer.

Introduction While porting 32-bit software to 64-bit systems there may appear some errors in the code of

applications which were written in C++ language. The cause for these hides in the alteration of the base

data types (to be more exact, in the relations between them) with the new hardware platform. "But isn't

C++ a high-level language!" you may ask, and you will be right. But still all the high-level abstractions are

realized through the low-level data types.

Help documentation for developers is sure to contain the description of such errors. However, even

such authoritative sources as, for example MSDN, often give only platitudes, for instance:

• int and long remained 32-bit ones with 64-bit versions of Widows;

• size_t, time_t, and ptrdiff_t became 64-bit ones with 64-bit versions of Windows.

But what does it mean for a developer and what problems may it potentially cause - all this is not

reported in the help.

Meanwhile, there are very few articles which contain certain examples of application code errors in 64-

bit Windows versions. This article is to fill the vacuum.

First of all some terminology. Memsize type is any data type which changes its size when the digit

capacity of architecture is changed from 32 bits to 64 bits. The examples are size_t, ptrdiff_t,

DWORD_PTR, LONG_PTR and others.

Take a note that only short examples of errors are given in the article. The explanation of their causes

are given in the article "20 issues of porting C++ of porting C++ code on the 64-bit platform"

http://www.viva64.com/art-1-2-599168895.html .

Page 2: Some examples of the 64-bit code errors

An error source code example Let us not harass the developers who wish to get down to studying the error examples, so let's show the

whole source code of such a program. After the source code each error will be considered separately.

To demonstrate the errors it is necessary to compile and run this code in the 64-bit mode.

You can find the source code of an application which contains this code in a Viva64 distributive named

PortSample. For this purpose download and install Viva64 (www.viva64.com/download.php) and then

install PortSamle from program folder Viva64.

bool IsX64Platform() {

return sizeof(size_t) == 8;

}

template <typename A, typename B>

inline size_t SafeMul(A a, B b) {

return static_cast<size_t>(a) * static_cast<size_ t>(b);

}

template <typename A, typename B, typename C>

inline size_t SafeMul(A a, B b, C c) {

return static_cast<size_t>(a) * static_cast<size_ t>(b) *

static_cast<size_t>(c);

}

template <typename A, typename B, typename C, typen ame D>

inline size_t SafeMul(A a, B b, C c, D d) {

return static_cast<size_t>(a) * static_cast<size_ t>(b) *

static_cast<size_t>(c) * static_cast<size_ t>(d);

}

void V101()

{

unsigned imageWidth = 1000;

unsigned imageHeght = 1000;

unsigned bytePerPixel = 3;

unsigned maxFrameCountInBuffer;

if (IsX64Platform()) {

Page 3: Some examples of the 64-bit code errors

maxFrameCountInBuffer = 2000;

} else {

maxFrameCountInBuffer = 100;

}

size_t bufferSize = imageWidth * imageHeght *

bytePerPixel * maxFrameCountI nBuffer;

BYTE *buffer = static_cast<BYTE *>(malloc(bufferS ize));

BYTE *ptr = buffer;

for (unsigned frame = 0; frame != maxFrameCountIn Buffer; ++frame)

for (unsigned width = 0; width != imageWidth; + +width)

for (unsigned height = 0; height != imageHegh t; ++height) {

*ptr++ = 0xFF;

*ptr++ = 0xFF;

*ptr++ = 0x00;

}

free (buffer);

}

void V102()

{

int domainWidth;

int domainHeght;

int domainDepth;

if (IsX64Platform()) {

domainWidth = 2000;

domainHeght = 2000;

domainDepth = 2000;

} else {

domainWidth = 500;

domainHeght = 500;

domainDepth = 500;

Page 4: Some examples of the 64-bit code errors

}

char *buffer =

new char [size_t(domainWidth) * size_t(domainHe ght) * size_t(domainDepth)];

char *current = buffer;

char *end = buffer;

end += domainWidth * domainHeght * domainDepth;

while (current != end)

*current++ = 1;

delete [] buffer;

}

void V103()

{

size_t Megabyte = 1048576;

size_t Gigabyte = 1073741824;

size_t n = IsX64Platform() ? Gigabyte : Megabyte;

unsigned arraySize = n * sizeof(INT_PTR);

INT_PTR *buffer = (INT_PTR *)malloc(size_t(arrayS ize));

for (size_t i = 0; i != n; ++i)

buffer[i] = 0;

free(buffer);

}

void V104()

{

volatile size_t n;

if (IsX64Platform()) {

n = SafeMul(5, 1024, 1024, 1024);

} else {

Page 5: Some examples of the 64-bit code errors

n = SafeMul(5, 1024, 1024);

}

char *buffer = new char [n];

volatile size_t index = 0;

volatile unsigned i;

for (i = 0; i != n; ++i)

buffer[index++] = 1;

delete [] buffer;

}

void V105()

{

bool flag = true;

unsigned a = unsigned(-1);

if ((flag ? a : sizeof(float)) != size_t(-1)) {

throw CString("x64 portability issues");

}

}

void V106()

{

void *buffer;

const unsigned Megabyte = 1024 * 1024;

const unsigned Gigabyte = 1024 * 1024 * 1024;

unsigned unit;

if (IsX64Platform())

unit = Gigabyte;

else

unit = Megabyte;

buffer = malloc(5 * unit);

Page 6: Some examples of the 64-bit code errors

if (IsX64Platform())

memset(buffer, 0, SafeMul(5, 1024, 1024, 1024)) ;

else

memset(buffer, 0, SafeMul(5, 1024, 1024));

free(buffer);

}

void V107_FillFunction(char *array, unsigned arrayS ize) {

for (unsigned i = 0; i != arraySize; ++i)

array[i] = 1;

}

void V107()

{

size_t n;

if (IsX64Platform()) {

n = SafeMul(5, 1024, 1024, 1024);

} else {

n = SafeMul(5, 1024, 1024);

}

char *array = (char *)malloc(n * sizeof(char));

memset(array, 0, n * sizeof(char));

V107_FillFunction(array, n);

for (size_t i = 0; i != n; ++i)

if (array[i] != 1)

throw CString("x64 portability issues");

free(array);

}

void V108()

{

size_t n;

if (IsX64Platform()) {

Page 7: Some examples of the 64-bit code errors

n = SafeMul(5, 1024, 1024, 1024);

} else {

n = SafeMul(5, 1024, 1024);

}

char *array = (char *)malloc(n * sizeof(char));

memset(array, 0, n * sizeof(char));

volatile int index = 0;

for (size_t i = 0; i != n; ++i) {

array[index++] = 1;

if (array[i] != 1)

throw CString("x64 portability issues");

}

free(array);

}

ptrdiff_t UnsafeCalcIndex(int x, int y, int width) {

volatile int result = x + y * width;

return result;

}

void V109()

{

int domainWidth;

int domainHeght;

if (IsX64Platform()) {

domainWidth = 50000;

domainHeght = 50000;

} else {

domainWidth = 5000;

domainHeght = 5000;

}

char *array = (char *)malloc(SafeMul(domainWidth, domainHeght));

Page 8: Some examples of the 64-bit code errors

for (int x = 0; x != domainWidth; ++x)

for (int y = 0; y != domainHeght; ++y) {

array[UnsafeCalcIndex(x, y, domainWidth)] = 5 5;

}

free(array);

}

int UnsafeStrLen(const char *text) {

const char *ptr = text;

while (*ptr != 0)

++ptr;

return ptr - text;

}

void V110()

{

size_t n;

CString trueSize;

if (IsX64Platform()) {

n = SafeMul(3, 1024, 1024, 1024);

trueSize = _T("3221225472");

} else {

n = SafeMul(3, 1024, 1024);

trueSize = _T("3145728");

}

char *str = (char *)malloc(n * sizeof(char));

memset(str, 'V', n * sizeof(char));

str[n - 1] = 0;

int len = UnsafeStrLen(str);

CString falseSize;

falseSize.Format(_T("%i"), len + 1);

free(str);

Page 9: Some examples of the 64-bit code errors

if (falseSize != trueSize)

throw CString(_T("x64 portability issues"));

}

void V111()

{

char invalidStr[100], validStr[100];

const char *invalidFormat = "%u";

const char *validFormat = "%Iu";

size_t a = SIZE_MAX;

sprintf_s(invalidStr, sizeof(invalidStr),invalidF ormat, a);

sprintf_s(validStr, sizeof(validStr), validFormat , a);

if (strcmp(invalidStr, validStr) != 0)

throw CString(_T("x64 portability issues"));

}

void V113()

{

size_t a = size_t(-1);

double b = a;

--a;

--b;

size_t c = b;

if (a != c)

throw CString(_T("x64 portability issues"));

}

void V114()

{

unsigned intPtr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 , 9 };

size_t *sizetPtr = (size_t *)(intPtr);

size_t sum = 0;

for (size_t i = 0; i != 10; ++i)

Page 10: Some examples of the 64-bit code errors

sum += sizetPtr[i];

if (sum != 45)

throw CString(_T("x64 portability issues"));

}

void V301()

{

class CWinAppTest {

public:

virtual void WinHelp(DWORD_PTR, UINT) {

::AfxMessageBox(_T("Cannot activate WinHelp") );

}

};

class CPortSampleApp : public CWinAppTest {

public:

virtual void WinHelp(DWORD, UINT) {

::AfxMessageBox(_T("WinHelp activated"));

}

};

CWinAppTest *Application = new CPortSampleApp();

Application->WinHelp(NULL, 0);

delete Application;

}

int _tmain(int argc, TCHAR* argv[])

{

V101();

V102();

V103();

V104();

V105();

V106();

Page 11: Some examples of the 64-bit code errors

V107();

V108();

V109();

V110();

V111();

V112();

V113();

V114();

V201();

V202();

V203();

V301();

return 0;

}

Now, when we see the whole code, let's consider the functions which contain errors. When we say that

a function contains an error we mean the following: the given code is able to compile and function in

the 32-bit regime, but after compiling for the64-bit regime its functioning becomes incorrect up to fall.

Implicit conversion to memsize type void V101()

{

unsigned imageWidth = 1000;

unsigned imageHeght = 1000;

unsigned bytePerPixel = 3;

unsigned maxFrameCountInBuffer;

if (IsX64Platform()) {

maxFrameCountInBuffer = 2000;

} else {

maxFrameCountInBuffer = 100;

}

size_t bufferSize = imageWidth * imageHeght *

Page 12: Some examples of the 64-bit code errors

bytePerPixel * maxFrameCountI nBuffer;

BYTE *buffer = static_cast<BYTE *>(malloc(bufferS ize));

BYTE *ptr = buffer;

for (unsigned frame = 0; frame != maxFrameCountIn Buffer; ++frame)

for (unsigned width = 0; width != imageWidth; + +width)

for (unsigned height = 0; height != imageHegh t; ++height) {

*ptr++ = 0xFF;

*ptr++ = 0xFF;

*ptr++ = 0x00;

}

free (buffer);

}

The problem is in the next line:

size_t bufferSize = imageWidth * imageHeght *

bytePerPixel * maxFrameCountI nBuffer;

All the varibles in the multiplation are of unsigned type, which in both 32-bit and 64-bit regimes

pssesses the sie of 32 bits. But the result of multiplation is written with a variable of size_t type which in

the 32-bit mode possesses the size coinciding with the size of unsigned type and they don't coincide in

the 64-bit mode. But the compiler fulfills the extention of the result type up to unsigned one.It seems

that there is no problem at all. But the problem exists! If the result of multplication exceeds 4 gigabytes

the overflow will occur and the result will be incorrect.

The use of non-memsize types for the pointers arithmetic void V102()

{

int domainWidth;

int domainHeght;

int domainDepth;

if (IsX64Platform()) {

domainWidth = 2000;

domainHeght = 2000;

domainDepth = 2000;

Page 13: Some examples of the 64-bit code errors

} else {

domainWidth = 500;

domainHeght = 500;

domainDepth = 500;

}

char *buffer =

new char [size_t(domainWidth) * size_t(domainHe ght) * size_t(domainDepth)];

char *current = buffer;

char *end = buffer;

end += domainWidth * domainHeght * domainDepth;

while (current != end)

*current++ = 1;

delete [] buffer;

}

The problem in the given code is the pointers arithmetic, to be more exact, the use of non-memsize

types for this arithmetic:

end += domainWidth * domainHeght * domainDepth;

The error is that with the 64-bit platform the pointer end will never have the increment larger than 4

gigabytes.

Implicit conversion of memsize type void V103()

{

size_t Megabyte = 1048576;

size_t Gigabyte = 1073741824;

size_t n = IsX64Platform() ? Gigabyte : Megabyte;

unsigned arraySize = n * sizeof(INT_PTR);

INT_PTR *buffer = (INT_PTR *)malloc(size_t(arrayS ize));

for (size_t i = 0; i != n; ++i)

Page 14: Some examples of the 64-bit code errors

buffer[i] = 0;

free(buffer);

}

There is an obvious error in the following code fragment.

unsigned arraySize = n * sizeof(INT_PTR);

It's the implicit conversion to the unsigned type of a variable of larger capacity (on a 64-bit platform).

Implicit conversion to memsize type in an arithmetic sentence void V104()

{

volatile size_t n;

if (IsX64Platform()) {

n = SafeMul(5, 1024, 1024, 1024);

} else {

n = SafeMul(5, 1024, 1024);

}

char *buffer = new char [n];

volatile size_t index = 0;

volatile unsigned i;

for (i = 0; i != n; ++i)

buffer[index++] = 1;

delete [] buffer;

}

It's strange but operations of comparing two variables may be also the source of trouble. In the

following line

for (i = 0; i != n; ++i)

the problem is that the variable i of unsigned type is compared to the variable n of size_t type, and after

that this variable extends. But as unsigned never exceeds 4 gigabytes , than i will never be larger than

this value. What do we have as a result? We have an infinite loop! as the conditions of i != n will always

be fulfilled.

Page 15: Some examples of the 64-bit code errors

Implicit conversion to memsize type in ?: operation void V105()

{

bool flag = true;

unsigned a = unsigned(-1);

if ((flag ? a : sizeof(float)) != size_t(-1)) {

throw CString("x64 portability issues");

}

}

This example is very much alike to the previous one, the problem can be found in the following line:

if ((flag ? a : sizeof(float)) != size_t(-1)) {

here the variable a is of unsigned type which may give an incorrect result when compared to size_t.

Why? Just because unsigned(-1) is not equal to size_t (-1).

Implicit conversion of a function argument to memsize type void V106()

{

void *buffer;

const unsigned Megabyte = 1024 * 1024;

const unsigned Gigabyte = 1024 * 1024 * 1024;

unsigned unit;

if (IsX64Platform())

unit = Gigabyte;

else

unit = Megabyte;

buffer = malloc(5 * unit);

if (IsX64Platform())

memset(buffer, 0, SafeMul(5, 1024, 1024, 1024)) ;

else

memset(buffer, 0, SafeMul(5, 1024, 1024));

free(buffer);

Page 16: Some examples of the 64-bit code errors

}

In the line

buffer = malloc(5 * unit);

the developer hoped to get a 5-gigabyte buffer with a 64-bit system. But an error will occur here. You

ask why? Just because the malloc() function possesses an argument of memsize type and 5 is quite an

appropriate value. But when (5 * unit) is multiplied an overflow will occur because the unit variable is of

unsigned type. The result will for sure be not 5 gigabytes.

Implicit conversion of a function argument of memsize type to the 32-bit

type void V107_FillFunction(char *array, unsigned arrayS ize) {

for (unsigned i = 0; i != arraySize; ++i)

array[i] = 1;

}

void V107()

{

size_t n;

if (IsX64Platform()) {

n = SafeMul(5, 1024, 1024, 1024);

} else {

n = SafeMul(5, 1024, 1024);

}

char *array = (char *)malloc(n * sizeof(char));

memset(array, 0, n * sizeof(char));

V107_FillFunction(array, n);

for (size_t i = 0; i != n; ++i)

if (array[i] != 1)

throw CString("x64 portability issues");

free(array);

}

In the line with function call

V107_FillFunction(array, n);

Page 17: Some examples of the 64-bit code errors

there occurs the conversion of type of the variable n to unsigned. This means truncation of the variable

value, the result of this is that not the whole array is filled.

The use of incorrect types for indexation void V108()

{

size_t n;

if (IsX64Platform()) {

n = SafeMul(5, 1024, 1024, 1024);

} else {

n = SafeMul(5, 1024, 1024);

}

char *array = (char *)malloc(n * sizeof(char));

memset(array, 0, n * sizeof(char));

volatile int index = 0;

for (size_t i = 0; i != n; ++i) {

array[index++] = 1;

if (array[i] != 1)

throw CString("x64 portability issues");

}

free(array);

}

If not a memsize type is used for array indexation, it is possible that there will occur an error like the

following:

array[index++] = 1;

The problem is the following: in case if there are more than 4 gigabytes of elements , you may not use

the variable of unsigned type.

Conversion to memsize type using a return value ptrdiff_t UnsafeCalcIndex(int x, int y, int width) {

volatile int result = x + y * width;

return result;

Page 18: Some examples of the 64-bit code errors

}

void V109()

{

int domainWidth;

int domainHeght;

if (IsX64Platform()) {

domainWidth = 50000;

domainHeght = 50000;

} else {

domainWidth = 5000;

domainHeght = 5000;

}

char *array = (char *)malloc(SafeMul(domainWidth, domainHeght));

for (int x = 0; x != domainWidth; ++x)

for (int y = 0; y != domainHeght; ++y) {

array[UnsafeCalcIndex(x, y, domainWidth)] = 5 5;

}

free(array);

}

It's amazing, but in this example the error is in the line:

return result;

The value result is of int type which will be implicitly expanded to ptrdiff_t. But the function

UnsafeCalcIndex() will never be able to return the index of the element following 2 gigabytes. It would

be more correct to say that the error is the wrongly chosen type of the variable result. In this case this

variable must be of UnsafeCalcIndex() type.

Conversion of memsize type using a return value int UnsafeStrLen(const char *text) {

const char *ptr = text;

while (*ptr != 0)

++ptr;

return ptr - text;

Page 19: Some examples of the 64-bit code errors

}

void V110()

{

size_t n;

CString trueSize;

if (IsX64Platform()) {

n = SafeMul(3, 1024, 1024, 1024);

trueSize = _T("3221225472");

} else {

n = SafeMul(3, 1024, 1024);

trueSize = _T("3145728");

}

char *str = (char *)malloc(n * sizeof(char));

memset(str, 'V', n * sizeof(char));

str[n - 1] = 0;

int len = UnsafeStrLen(str);

CString falseSize;

falseSize.Format(_T("%i"), len + 1);

if (falseSize != trueSize)

throw CString(_T("x64 portability issues"));

}

The situation is the same as in the previous example and the error is again in the line of the return value:

return ptr - text;

The difference is that here we deal with the conversion of memsize type to int type. The result is that

the buffer size (from the example) will never be figured out if it is larger than 2 gigabytes.

Call of function with variable number of arguments with memsize

parameter void V111()

{

char invalidStr[100], validStr[100];

Page 20: Some examples of the 64-bit code errors

const char *invalidFormat = "%u";

const char *validFormat = "%Iu";

size_t a = SIZE_MAX;

sprintf_s(invalidStr, sizeof(invalidStr),invalidF ormat, a);

sprintf_s(validStr, sizeof(validStr), validFormat , a);

if (strcmp(invalidStr, validStr) != 0)

throw CString(_T("x64 portability issues"));

}

Functions with variable number of arguments are often used for formatting and input/output of text

lines. Incorrect presetting of the format line may cause incorrect work.

const char *invalidFormat = "%u";

sprintf_s(invalidStr, sizeof(invalidStr),invalidF ormat, a);

The format line in this example is estimated for 32-bit mode of working and in 64-bit mode it will cause

incorrect output.

Implicit conversion of memsize type to double and vice versa void V113()

{

size_t a = size_t(-1);

double b = a;

--a;

--b;

size_t c = b;

if (a != c)

throw CString(_T("x64 portability issues"));

}

In this example there are errors in two lines:

double b = a;

and

size_t c = b;

Such asignment with 64-bit systems is incorrect because it may cause loss of preision.

Page 21: Some examples of the 64-bit code errors

Explicit type conversion if the course of work with pointers void V114()

{

unsigned intPtr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 , 9 };

size_t *sizetPtr = (size_t *)(intPtr);

size_t sum = 0;

for (size_t i = 0; i != 10; ++i)

sum += sizetPtr[i];

if (sum != 45)

throw CString(_T("x64 portability issues"));

}

C++ being a low-level language allows working with memory at the pointer level. Explicit type

conversion using pointers is anyway dangerous, but conversion of memsize types , as shown in the

example, is twice dangerous.

size_t *sizetPtr = (size_t *)(intPtr);

The matter is the difference of types size_t and unsigned.

Overriding virtual functions void V301()

{

class CWinAppTest {

public:

virtual void WinHelp(DWORD_PTR, UINT) {

::AfxMessageBox(_T("Cannot activate WinHelp") );

}

};

class CPortSampleApp : public CWinAppTest {

public:

virtual void WinHelp(DWORD, UINT) {

::AfxMessageBox(_T("WinHelp activated"));

}

Page 22: Some examples of the 64-bit code errors

};

CWinAppTest *Application = new CPortSampleApp();

Application->WinHelp(NULL, 0);

delete Application;

}

One of the funniest errors of C++ applications which can appear with 64-bit systems is related to virtual

functions. Pay your attention to the parameters of virtual functions in the example above. With a 32-bit

system DWORD_PTR and DWORD coincide and there appears an overridden virtual function, and with a

64-bit platform there are two different functions! As a result the call of WinHelp() function from the

example will cause the appearance of "Cannot activate WinHelp" message.

Pro conclusion Thus, we have listed all the main code errors which appear when a code is ported to 64-bit systems. You

might think many of them are sophisticated. For example, who, for God's sake, may need a 5 gigabyte

buffer at Windows system? Maybe this problem is not very acute in 2007, though many resource-

intensive applications are already able to use such amount of memory. We'll see if this article will be

actual in a couple of years. Maybe just you will debug an error which appears when several gigabytes of

memory are allocated.

Some information about the author Evgeniy Ryzhkov is one of the developers of the static code analyzer Viva64 which is meant for

simplifying the migration of applications to 64-bit platforms. He studies the migration of 32-bit program

systems to 64-bit platforms.