The forgotten problems of 64-bit programs development

The Untouched Problems of 64-bit Programs Development

Let us start with the beginning. The authors of some articles don’t take into consideration large memory capacity that became available to modern applications. Of course, the pointers were 64-bit in ancient times yet, but such programs didn’t have chance to use arrays of several gigabytes in size. As a result, both in old and new articles there appeared a whole stratum of errors connected with the mistakes of indexation of big arrays. It is practically impossible to find a description of a mistake in the articles similar to the following:

for (int x = 0; x != width; ++x)
  for (int y = 0; y != height; ++y)
    for (int z = 0; z != depth; ++z)
      BigArray[z * width * height + y * width + x] = InitValue;

In this example the expression "z * width * height + y * width + x", which is used for addressing, has the int type, which means that the code will be incorrect at the arrays containing more that 2 GB of elements. At the 64-bit systems for a safer indexation to large arrays such types as ptrdiff_t, size_t should be used or their derivatives. The absence of the description of such kind of a mistake in the article can be easily explained. In the time when they were written the machines with memory capacity, which makes it possible to store such arrays were practically not available. Now it becomes a common task in programming, and we can watch with a great surprise how the code that has been serving faithfully for many years stopped working correctly dealing with big data arrays at 64-bit systems.

The other stratum of problems, which has not been touched upon, is represented by the mistakes connected with the possibilities and peculiarities of C++ language. It also quite explicable why it happened so. During the introduction of first 64-bit systems C++ language did not exist for them or was not spread. That’s why practically all the articles are devoted to the problems in the field of C language. Modern authors substituted the name C with C/C++ but they didn’t contribute anything new.

But the absence of the mistakes typical of C++ in the articles does not mean that they don’t exist. There are such mistakes that show up during the migration of programs to 64-bit systems. They are connected with virtual functions, exceptions, overloaded functions and so on. You may get acquainted with such mistakes in article [8] in more detail. Let us give an example connected with using virtual functions.

?lass CWinApp {
  ...
  virtual void WinHelp(DWORD_PTR dwData, UINT nCmd);
};
class CSampleApp : public CWinApp {
  ...
  virtual void WinHelp(DWORD dwData, UINT nCmd);
};

Let us follow the life cycle of development of a certain application. Let us suppose that first it wa developed to Microsoft Visual C++ 6.0. when WinHelp function in CWinApp class had the following prototype:

virtual void WinHelp(DWORD dwData, UINT nCmd = HELP_CONTEXT);

It was right to realize the overriding a virtual function in CSampleApp class like it is show in the example. Then the project was ported to Microsoft Visual C++ 2005 where the prototype of the function in CWinApp class underwent changes that consisted in changing DWORD type into DWORD_PTR type. The program will continue working correctly at a 32-bit system for the DWORD and DWORD_PTR types coincide here. The problems will show up during the compilation of the code to 64-bit platform. There will come out two functions with identical names but with different parameters, in the result of what the user’s code will not be able to activate.

Besides the peculiarities of 64-bit programs development from the point of view of C++ language there exist other moments to be paid attention to. For example, the peculiarities connected with the architecture of 64-bit Windows version. We’d like to let developer know about possible problems and to recommend to pay more attention to testing 64-bit software.

Now let us get back to the methods of verification of the source code using static analyzers. I think you have already guessed that everything is not so nice here as it may seem. In spite of the declared support in diagnosing the peculiarities of 64-bit code, this support at the moment does not meet the necessary demands. The reason is that the diagnostic rules were created according to all those articles that do not take into account the specific character of C++ language or processing large data arrays, that exceed 2 GB.

For Windows developers the case is somewhat worse. The main static analyzers are rated at diagnosing 64-bit errors for LP64 data model while in Windows LLP64 data model is used [10]. The reason is that 64-bit Windows versions are young and older 64-bit systems were represented by Unix-like systems with LP64 data model.

As an example let us consider the diagnostic message 3264bit_IntToLongPointerCast (port-10), which is generated by the analyzer Parasoft C++test.

int *intPointer;	
long *longPointer;
longPointer = (long *)intPointer; //-ERR port-10

C++test presupposes that from the point of view of LP64 model this construction will be incorrect. But in the scope of data model accepted in Windows this construction will be safe.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“We better hurry up and start coding, there are going to be a lot of bugs to fix.”