How to run a 32 bit program on 64 windows 7

Most modern games like Overwatch, Hurtworld or Subnautica can only run on 64-bit operating systems. It is simply not profitable for the creators of these programs to make different versions of applications for 32- and 64-bit. Although both versions are quite common. Of course, switching to x64 is quite easy. But what if you are not going to change the OS and still want to watch a popular game? Learn how to run Subnautica and other 64-bit programs on a 32-bit system.

To do this, the computer must meet the requirements necessary for the normal operation of the application. The processor must initially have x64 architecture.

What is the difference between a 32-bit system and a 64-bit one?

Why can’t programs designed for 64 bit open on 32 bit? Why are these versions so different, since they do not run the same applications? And if Overwatch can be played on x64, why can't it be played on the same computer, but with x32?

It depends on the system how much RAM can be installed on a PC and how much it can allocate to each specific application. In x64, the maximum amount of RAM is 16 GB (in Windows 7 Professional - up to 192 GB). In this case, any utility is provided with up to 4 GB. In the x32 version, the indicated numbers are much smaller - 4 GB maximum and 2 GB for a separate program.

The capacity of the processor determines how it processes information. This significantly affects performance - it is much better in 64 bit. There is a larger register for storing data, and the load is distributed across all cores at once. And in a 32-bit OS, the second core is activated when the first is fully occupied.

On “weak” machines install x32. If your PC doesn't have a lot of RAM and doesn't have the best processor, there's simply no point in running 64 bit. This will only “overload” the electronic computer without adding productivity to it. But a powerful x64 computer will be just right.

Although these systems are superficially similar to each other, they are very different at the software level. They have a different set of drivers, so Subnautica, Overwatch, Hurtworld and others like that will not run on a 32-bit OS, even if the PC has the necessary characteristics.

For modern games, applications, graphics or video editing programs, the 2 GB that x32 allocates to them is not enough. Composers of new games create their products specifically for x64.

How to find out if a processor supports x64?

You can see what OS you have installed like this:

  1. On your desktop, right-click on the “My Computer” icon.
  2. “Properties” item. It can also be found in the Control Panel section.
  3. The "Type" line will indicate how many bits there are in your OS version.

First you need to understand what system you are working on.

Before you run Overwatch on a 32-bit system, find out if your PC can handle the game. Check if the processor supports 64-bit instructions. This can be done using special tester programs. For example, the free utility “SecurAble” is suitable. It doesn't need to be installed. And, accordingly, there is no need to remove it after use. Just run the executable. Information about the processor will be shown: name, clock speed, bit depth, whether it supports D.E.P (this is the protection of the device against buffer overflow) and hardware visualization. You can click on any of the results and its description will appear.

Checking processor support for 64-bit commands

If the program returns a verdict of “Maximum 32 bit,” it means that applications designed for x64 are unlikely to work. To play Overwatch or Hurtword, you will have to change the processor or dispose of remote servers.

How to turn a 32-bit system into a 64-bit one?

There are several utilities for so-called virtualization. They emulate the operation of a platform with certain software and hardware. If you need to figure out how to run Hurtworld on a 32-bit system, use one of these utilities.

These programs create a kind of “guest” OS. But you must install it in any case and purchase a licensed version if it is paid. To do this, you must have a disk (or disk image) with the operating system that you need.

Oracle VirtualBox

A universal program for similar tasks.

  1. Install it and run it. On the left there will be a list of installed operating systems and a toolbar. On the right is information about the selected system.
  2. Click the "Create" button. An information window will appear. Click "Next".
  3. Select OS type and version. There are many options to choose from: not only Microsoft windows, but also Linux.
  4. Then you will need to decide how much RAM to allocate to the “guest” system.
  5. After this, you need to create a virtual disk (to which the OS files will be written). You can choose an existing one or make a new one. And check the box next to the “Boot disk” option.
  6. In the next window, select whether the disk capacity will be fixed or dynamic (changing). There are detailed explanations for each item. It is better to make the boot one fixed. You can add more drives later.
  7. Configure the virtual storage size. Usually 10 GB is enough. It is better to create it in a separate place - not in the same place where the main system is installed.
  8. Wait for the process to complete. A new one will appear in the list of available ones.

One way is to use virtualization utilities

Afterwards you can configure the hardware:

  1. Select the guest OS and click Properties.
  2. In the General - Advanced section, change the folder for saving pictures to the one that is convenient for you.
  3. Set up the clipboard there. It determines how information will be transferred between different operating systems.
  4. In the “System” tab, you can select the characteristics of the virtual motherboard and processor.
  5. The “Network” item is needed to configure access to the World Wide Web. You can leave the default settings.
  6. In the “Media” section, indicate where you want to get the OS from. If the installer is on a CD, insert it into your drive. To download from .ISO, click on the “Open” button next to the “Drive” list. It looks like a yellow folder.
  7. You can also add other images there to quickly switch between them: databases, applications, games.

After completing the settings, click “OK”. To start the guest OS, click on it and the “Start” button. The installation will proceed. And you can switch between systems: play in 64-bit and work in 32-bit.

Other virtual machines

There are also utilities for working with virtual machines:

  • VMware Workstation. A serious professional program for complex tasks. It is distributed on a paid basis.
  • A simple utility for hardware emulation. It is open source.
  • windows Virtual PC. Works only with Windows systems. You can configure the priority of processes - this way resources will be automatically allocated to the online machine if it performs a certain task.
  • Virt-Manager. Provides ample opportunities for customizing the hardware component - virtual hardware is available for every taste.

Cloud computing (remote servers)

If the performance is still not enough to run the game, you can do it on a remote server. All calculations, all information will be processed on it. This way you won't be hindered by any limitations associated with x32. After all, in essence, applications will “open” on suitable systems. Just not on your computer.

The Microsoft Azure program is suitable for this. With its help, you can create several operating systems for different purposes. Game lovers will also find the specialized NVIDIA GRID video card virtualization service useful. These utilities require high-speed Internet.

Cutting-edge cloud services expand our capabilities

Working with 64-bit applications on a 32-bit system is quite possible. But you need to install additional software or, in general, switch to a remote server. This is quite difficult to do. If you want to fully play Overwatch, Hurtword and other popular games, it is better to install x64 OS. This way there will be no compatibility problems. And you won't have to configure anything.

NastroyVse.ru

windows x64 - Why are there still so many 32-bit programs?

Your computer is most likely running a 64-bit version of Windows. But if you open Task Manager, you will see that most of the programs on your system are still 32-bit. Is this really a problem? There are many differences between 64-bit and 32-bit versions of windows. 64-bit versions of windows can run 32-bit software, but 32-bit versions of windows cannot run 64-bit software.

How to find out the bit depth of a program?

Let's use Task Manager to see which of your programs are 64-bit and which are 32-bit. Right-click on the taskbar and select Task Manager or press Ctrl + Shift + Esc to open it. Look at the column with process names. If you are using the 64-bit version of Windows 8.1 or 8, you will see the word “(32-bit)” after each 32-bit version of the program name. If you are using the 64-bit version of Windows 7, you will see “*32” instead. 32-bit programs are typically installed in the C:\Program Files (x86)\ folder on 64-bit versions of windows, while 64-bit programs are typically installed in the C:\Program Files\ folder. It's just a rule. But no one is saying that there is no other rule that prohibits installing 64-bit programs in the C:\Program Files (x86)\ folder. For example, Steam is a 32-bit program, so it installs in "C:\Program Files (x86)\" by default. The games you install on Steam are installed in the C:\Program Files (x86)\Steam folder by default, incl. even 64-bit versions of games. If you compare two different Program Files folders, you will find that most of your programs are most likely installed in the C:\Program Files (x86) folder. And, these programs are mostly 32-bit.

Running 32-bit software on a 64-bit operating system

At first glance, it seems terrible that most of your Windows programs do not use the 64-bit operating system architecture. You might think that there is a performance penalty for running 32-bit programs on a 64-bit operating system, but this is not the case. windows runs 32-bit programs through the WoW64 compatibility level on 64-bit versions of windows. However, 64-bit Intel and AMD processors are backward compatible and can directly run 32-bit software. All your 32-bit Windows programs will run just as they would on a 32-bit version of Windows. Thus, there is no obstacle to running these programs on a 64-bit operating system. Even if every program you use is still 32-bit, you will benefit because your operating system itself will be running in 64-bit mode. And, the 64-bit version of Windows is more secure.

64-bit programs and 32-bit programs: which is better?

32-bit programs run without problems on 64-bit versions of Windows operating systems. But would it be better if all your programs were 64-bit? There are definitely advantages to 64-bit programs. 32-bit programs can only use 2 GB of memory, while 64-bit programs can use much more. If a program is likely to come under attack, additional security features applied to 64-bit programs may help. Google Chrome is currently a 32-bit application even on 64-bit versions of Windows OS, but a 64-bit beta version of this program has already appeared. And Google promises that the 64-bit version of Chrome will be faster, more secure and more stable. Some programs offer 64-bit versions. For example: Photoshop, iTunes, Microsoft Office, and some of the most popular windows programs, and they are all available in 64-bit form. Latest games are also often 64-bit so they can use more than 2GB of memory. Many programs haven't made the transition to 64-bit, and most never will. You can still run most 32-bit Windows programs today, even those that were released ten years ago, on a 64-bit version of Windows, even if their developers have already updated them. A developer who wants to provide a 64-bit version of their program must do a lot of extra work. He must ensure that the existing code compiles and runs correctly as 64-bit software. It must provide and support two separate versions of the program, since users running a 32-bit version of Windows cannot use the 64-bit version. Let's take Evernote for Windows desktop as an example. Even if they released a 64-bit version of Evernote, users would likely not notice the difference at all. A 32-bit program can run just fine on a 64-bit version of Windows, and if there are no noticeable benefits, then there is no point in having a 64-bit version.

Where to find 64-bit applications

You generally will not be able to choose between 32-bit and 64-bit versions of the software. For example, when you install iTunes for Windows, Apple's website automatically directs you to either the 32-bit or 64-bit version of the installer, depending on your version of Windows. When installing Photoshop for Windows, both 32-bit and 64-bit executable files are usually installed. Photoshop automatically selects from them. Sometimes you may see separate download links for 32-bit and 64-bit versions of programs, but this is not that common. The important thing is not to search for 64-bit applications, but to find applications that work well for you. For most applications, it doesn't really matter whether the version is 64-bit or 32-bit.

It's easy to wonder why so many applications are still 32-bit when you open your task manager. But this is not a very big problem and here's why. Because most applications do not gain anything when switching to 64-bit editions of programs. Even if the developers did all the work and released 64-bit versions of all the little desktop applications and utilities you use on Windows, you wouldn't be able to tell the difference for most of them.

itchief.ru

7 steps to transfer a program to a 64-bit system

The article discusses the main steps to ensure the correct transfer of 32-bit Windows applications to 64-bit Windows systems. Although the article is aimed at developers using the C/C++ language in Visual Studio 2005/2008, it will also be useful to other developers planning to port their applications to 64-bit systems. The article describes the main points faced by developers planning to migrate 32-bit programs to 64-bit systems. Of course, the list of issues considered is not complete, but I would like to hope that over time an expanded version of this article will be offered. The author will be grateful for feedback, comments and questions that will improve the information content of this article. In computing architecture, the term "64-bit" refers to 64-bit integers and other data types that are 64 bits in size. "64-bit" systems can mean 64-bit microprocessor architectures (for example, EM64T, IA-64) or 64-bit operating systems (for example, windows XP Professional x64 Edition). AMD64 (aka x86-64, Intel 64, EM64T, x64) is a 64-bit microprocessor architecture and corresponding instruction set developed by AMD. This instruction set was licensed by Intel under the name EM64T (Intel64). The AMD64 architecture is an extension of the x86 architecture with full backward compatibility. The architecture has become widespread as a base for personal computers and workstations. IA-64 is a 64-bit microprocessor architecture jointly developed by Intel and Hewlett Packard. Implemented in Itanium and Itanium 2 microprocessors. The architecture is used mainly in multiprocessor servers and cluster systems. AMD64 and IA-64 are two different 64-bit architectures that are not compatible with each other. Therefore, developers should immediately decide whether they need to support both of these architectures or just one. In most cases, unless you are developing highly specialized software for cluster systems or implementing your own high-performance DBMS, then most likely you only need to implement support for the AMD64 architecture, which is much more widespread than IA-64. This is especially true for software for the personal computer market, which is almost 100 percent occupied by the AMD64 architecture. Further in the article we will talk only about the AMD64 architecture (EM64T, x64), since its use is now most relevant for application software developers.

Speaking about various architectures, we should mention the concept of “Data Model”. A data model should be understood as a relationship between the dimensions of types accepted within the development environment. For one operating system, there may be several development tools that adhere to different data models. But usually only one model prevails, the one that best matches the hardware and software environment. An example is the 64-bit Windows operating system, in which the native data model is LLP64. But for compatibility, the 64-bit Windows system supports the execution of 32-bit programs that run in the ILP32LL data model mode. Table N1 provides information about the main data models.


Table N1. Data Models

The data model used affects the development process of 64-bit applications, since the program code must take into account the bit depth of the data used.

You should start mastering 64-bit systems with the question “Do we need to rebuild our project for a 64-bit system?” This question must be answered, but not in a hurry, after thinking. On the one hand, you can fall behind your competitors by not offering 64-bit solutions in time. On the other hand, you can waste your time on a 64-bit application that will not provide any competitive advantages. We list the main factors that will help you make a choice. You should not create a 64-bit version of an application with a short life cycle. Thanks to the WOW64 subsystem, old 32-bit applications work quite well on 64-bit Windows systems and therefore it makes no sense to make a 64-bit program that will no longer be supported in 2 years. Moreover, practice has shown that the transition to 64-bit versions of Windows has been delayed and perhaps the majority of your users in the short term will use only the 32-bit version of your software solution. If you plan for long-term development and long-term support of a software product, then you should start working on the 64-bit version of your solution. This can be done slowly, but keep in mind that the longer you do not have a full-fledged 64-bit version, the more difficulties may arise with supporting such an application installed on 64-bit versions of Windows. Recompiling the program for a 64-bit system will allow it to use huge amounts of RAM, and will also speed up its operation by 5-15%. A 5-10% speedup will occur due to the use of architectural capabilities of a 64-bit processor, for example, a larger number of registers. Another 1%-5% increase in speed is due to the absence of the WOW64 layer, which translates API calls between 32-bit applications and the 64-bit operating system. If your program does not work with large amounts of data (more than 2GB) and its speed is not critical, then switching to a 64-bit system in the near future is not so relevant. By the way, even simple 32-bit applications can benefit from running them in a 64-bit environment. You probably know that a program compiled with the /LARGEADDRESSAWARE:YES key can allocate up to 3 gigabytes of memory if the 32-bit Windows operating system is launched with the /3gb key. The same 32-bit program running on a 64-bit system can allocate almost 4 GB of memory (in practice, about 3.5 GB). If you develop libraries, components, or other elements that third-party developers use to create their software, then you must be proactive in creating a 64-bit version of your product. Otherwise, your customers interested in releasing 64-bit versions will be forced to look for alternative solutions. For example, some software and hardware protection developers responded with a long delay to the emergence of 64-bit programs, which forced a number of clients to look for other tools to protect their programs. An additional benefit of releasing a 64-bit version of the library is that you can sell it as a separate product. Thus, your customers who want to create both 32-bit and 64-bit applications will be forced to purchase 2 different licenses. For example, this policy is used by Spatial Corporation when selling the Spatial ACIS library. Before you plan to create 64-bit versions of your product, find out whether there are 64-bit versions of the libraries and components that it uses. Also find out what the pricing policy is for the 64-bit version of the library. All this can be found out by visiting the website of the library developer. If support is not available, then look in advance for alternative solutions that support 64-bit systems. If your solutions still contain 16-bit modules, then it's time to get rid of them. Running 16-bit applications on 64-bit versions of Windows is not supported. Here we should clarify one point related to the use of 16-bit installers. They are still used to install some 32-bit applications. A special mechanism has been created that on the fly replaces a number of the most popular 16-bit installers with newer versions. This may cause the misconception that 16-bit programs still run in a 64-bit environment. Remember, this is not true. Don't forget that using a large amount of assembly code can significantly increase the cost of creating a 64-bit version of the application. After weighing all the listed facts, all the pros and cons, decide whether you should port your project to 64-bit systems. And if that's the case, then let's move on. Just because you've decided to develop a 64-bit version of your product and are willing to spend time on it doesn't guarantee success. The fact is that you must have all the necessary tools and there may be unpleasant incidents here.

The simplest, but also the most insurmountable, problem may be the lack of a 64-bit compiler. The article is written in 2009, but there is still no 64-bit C++ Builder compiler from Codegear. Its release is expected only by the end of this year. It is impossible to get around a similar problem, unless, of course, you rewrite the entire project, for example, using Visual Studio. But if everything is clear with the lack of a 64-bit compiler, then other similar problems may turn out to be more hidden and emerge already at the stage of work on transferring the project to a new architecture. Therefore, I would like to advise you to conduct research in advance to determine whether all the necessary components exist that will be required to implement the 64-bit version of your product. Unpleasant surprises may await you.

Of course, it is impossible to list everything that may be needed for a project here, but I will still offer a list that will help you get your bearings and perhaps remember other points that are necessary for the implementation of your 64-bit project: It is difficult to say anything else about the importance of having 64-bit compiler. It just has to be. If you plan to develop 64-bit applications using the latest version (at the time of writing) of Visual Studio 2008, then the following table N2 will help determine which edition of Visual Studio you need.

Table N2. Capabilities of different editions of Visual Studio 2008 You can, of course, use virtual machines to run 64-bit applications on 32-bit hardware, but this is extremely inconvenient and will not provide the required level of testing. It is advisable that machines have at least 4-8 gigabytes of RAM installed. If libraries are provided in source code, then a 64-bit project configuration must be present. Upgrading a library yourself to build it for a 64-bit system can be a thankless and difficult task, and the result can be unreliable and error-prone. You may also violate license agreements by doing so. If you are using libraries as binary modules, then you should also find out if 64-bit modules exist. You won't be able to use 32-bit DLLs inside a 64-bit application. You can create a special harness via COM, but this will be a separate large, complex task. Also note that purchasing the 64-bit version of the library may cost additional money. Visual C++ does not support 64-bit inline assembler. You must use either an external 64-bit assembler (for example, MASM) or have a C/C++ implementation of the same functionality. Significant revision of testing methodology, modernization of unit tests, use of new tools. This will be discussed in more detail below, but do not forget to take this into account when estimating the time spent migrating an application to a new system. If you are developing resource-intensive applications that consume a large amount of RAM, then you need to take care of replenishing the database of test input data. When load testing 64-bit applications, it is advisable to go beyond 4 gigabytes of memory consumption. Many errors can only appear under such conditions. The protection system used must support 64-bit systems to the full extent you require. For example, Aladdin quickly released 64-bit drivers to support Hasp hardware keys. But for a very long time there was no system for automatic protection of 64-bit binary files (Hasp Envelop program). Thus, the protection mechanism had to be implemented independently within the program code, which was an additional complex task that required qualifications and time. Don’t forget about similar issues related to security, the update system, and so on. You need a new installer that can fully install 64-bit applications. I would like to immediately warn you about one traditional mistake. This is the creation of 64-bit installers for installing 32/64-bit software products. When preparing a 64-bit version of an application, developers often want to make it completely 64-bit. And they create a 64-bit installer, forgetting that users of a 32-bit operating system simply will not run such an installation package. Please note that it is not the 32-bit application included in the distribution along with the 64-bit that will not start, but the installer itself. After all, if the distribution is a 64-bit application, then, of course, it will not run on a 32-bit operating system. The most annoying thing about this is that the user will not be able to guess what is happening. He will simply see an installation package that cannot be launched. Creating a 64-bit project configuration in Visual Studio 2005/2008 looks quite simple. Difficulties will await you at the stage of assembling a new configuration and searching for errors in it. To create a 64-bit configuration, just complete the following 4 steps: Launch the configuration manager, as shown in Figure N1:

Figure 1. Launching the configuration manager In the configuration manager, select support for the new platform (Figure N2): Figure 2. Creating a new configuration Select the 64-bit platform (x64), and select the settings from the 32-bit version as the basis (Figure N3). The Visual Studio environment will adjust the settings that affect the build mode itself.

Figure 3. Select x64 as the platform and use the Win32 configuration as a basis. Adding a new configuration is completed, and we can select the 64-bit configuration option and begin compiling the 64-bit application. The choice of 64-bit configuration for assembly is shown in Figure N4. Figure 4. 32-bit and 64-bit configurations are now available. If you are lucky, there will be no need to additionally configure a 64-bit project. But this greatly depends on the project, its complexity and the number of libraries used. The only thing that needs to be changed right away is the stack size. If your project uses a default stack size, that is, 1 megabyte, then it makes sense to set it to 2 megabytes for the 64-bit version. This is not necessary, but it is better to be on the safe side in advance. If you use a stack size different from the default size, then it makes sense to make it 2 times larger for the 64-bit version. To do this, in the project settings, find and change the Stack Reserve Size and Stack Commit Size parameters. Here it would be good to talk about typical problems that arise during the compilation stage of a 64-bit configuration. Consider what problems arise with third-party libraries, tell that the compiler in the code associated with WInAPI functions will no longer allow placing a pointer in the LONG type and you will need to modernize your code and use the LONG_PTG type. And many many others. Unfortunately, there is so much of this and the errors are so varied that it is not possible to present it in one article or even, perhaps, a book. You will have to look through all the errors that the compiler will produce and new warnings that were not there before and in each individual case figure out how to modernize the code.

A collection of links to resources dedicated to the development of 64-bit applications can make life partly easier: http://www.viva64.com/links/64-bit-development/. The collection is constantly being updated and the author will be grateful to readers if they send him links to resources that, in their opinion, deserve attention.

We will focus here only on the types that may be of interest to developers when migrating applications. These types are presented in Table N3. Most compilation errors will be associated with the use of these types.

Type Dimensiontype on platform x32 / x64 Note
int 32 / 32 Basic type. On 64-bit systems it remains 32-bit.
long 32 / 32 Basic type. On 64-bit Windows systems it remains 32-bit. Please note that on 64-bit Linux systems this type has been extended to 64-bit. Don't forget about this if you are developing code that should work and compile for Windows and Linux systems.
size_t 32 / 64 Basic unsigned type. The size of the type is chosen so that it can accommodate the maximum size of a theoretically possible array. A pointer can be safely placed into the type size_t (the exception is pointers to class functions, but this is a special case).
ptrdiff_t 32 / 64 Similar to the size_t type, but signed. The result of an expression where one pointer is subtracted from another (ptr1-ptr2) will be of type ptrdiff_t.
Pointer 32 / 64 The size of the pointer directly depends on the bit capacity of the platform. Be careful when casting pointers to other types.
__int64 64 / 64 Signed 64-bit type.
DWORD 32 / 32 32-bit unsigned type. Declared in WinDef.h as: typedef unsigned long DWORD;
DWORDLONG 64 / 64 64-bit unsigned type. Declared in WinNT.h as: typedef ULONGLONG DWORDLONG;
DWORD_PTR 32 / 64 An unsigned type that can hold a pointer. Declared in BaseTsd.h as: typedef ULONG_PTR DWORD_PTR;
DWORD32 32 / 32 32-bit unsigned type. Declared in BaseTsd.h as: typedef unsigned int DWORD32;
DWORD64 64 / 64 64-bit unsigned type. Declared in BaseTsd.h as: typedef unsigned __int64 DWORD64;
HALF_PTR 16 / 32 Half a pointer. Declared in Basetd.h as:#ifdef _WIN64 typedef int HALF_PTR;#else typedef short HALF_PTR;#endif
INT_PTR 32 / 64 A signed type into which a pointer can be placed. Declared in BaseTsd.h as:#if defined(_WIN64) typedef __int64 INT_PTR; #else typedef int INT_PTR;#endif
LONG 32 / 32 A signed type that remains 32-bit. Therefore, in many cases LONG_PTR should now be used. Declared in WinNT.h as: typedef long LONG;
LONG_PTR 32 / 64 A signed type into which a pointer can be placed. Declared in BaseTsd.h as:#if defined(_WIN64) typedef __int64 LONG_PTR; #else typedef long LONG_PTR;#endif
LPARAM 32 / 64 Parameter for sending messages. Declared in WinNT.h as: typedef LONG_PTR LPARAM;
SIZE_T 32 / 64 Analogous to the size_t type. Declared in BaseTsd.h as: typedef ULONG_PTR SIZE_T;
SSIZE_T 32 / 64 Analogous to the ptrdiff_t type. Declared in BaseTsd.h as: typedef LONG_PTR SSIZE_T;
ULONG_PTR 32 / 64 An unsigned type that can hold a pointer. Declared in BaseTsd.h as:#if defined(_WIN64) typedef unsigned __int64 ULONG_PTR;#else typedef unsigned long ULONG_PTR;#endif
WORD 16 / 16 Unsigned 16-bit type. Declared in WinDef.h as: typedef unsigned short WORD;
WPARAM 32 / 64 Parameter for sending messages. Declared in WinDef.h as: typedef UINT_PTR WPARAM;
Table N3. Types of interest when porting 32-bit programs to 64-bit Windows systems. If you think that after correcting all compilation errors the long-awaited 64-bit application will be obtained, then you will have to be disappointed. The hardest part is yet to come. At the compilation stage, you will correct the most obvious errors that the compiler could detect, which are mainly related to the impossibility of implicit type casting. But this is the tip of the iceberg. Most of the errors are hidden. From the point of view of the abstract C++ language, these errors look safe or are disguised by explicit type casts. There are several times more such errors than the number of errors identified at the compilation stage.

You shouldn't pin your hopes on the /Wp64 key. This key is often touted as a miracle tool for finding 64-bit errors. In fact, the /Wp64 switch only makes it possible, when compiling 32-bit code, to receive some warnings that certain sections of the code will be incorrect in 64-bit mode. When compiling 64-bit code, these warnings will be issued by the compiler in any case. And therefore, when compiling a 64-bit application, the /Wp64 key is ignored. And even more so, this key will not help in finding hidden errors.

Let's look at a few examples of hidden errors. The simplest, but not the easiest to detect, class of errors is associated with explicit type casting, in which significant bits are cut off. A common example is casting pointers to 32-bit types when passing them to functions such as SendMessage:

MyObj* pObj = ... ::SendMessage(hwnd, msg, (WORD)x, (DWORD)pObj);
Here an explicit type cast is used to convert a pointer to a numeric type. For a 32-bit architecture, the above example is correct, since the last parameter of the SendMessage function is of type LPARAM, which is the same as DWORD on a 32-bit architecture. For 64-bit architecture, the use of DWORD is erroneous and should be replaced with LPARAM. The LPARAM type has a size of 32 or 64 bits, depending on the architecture.

This is a simple case, but often the type cast looks more sophisticated and cannot be detected using compiler warnings or searching through the program text. Explicit type casts suppress compiler diagnostics because they are intended to tell the compiler that the type cast is correct and the programmer has accepted responsibility for the safety of the code. An explicit search won't help either. Types may not have standard names (specified by the programmer via typedef), and there are also quite a few ways to implement explicit type casting. To reliably diagnose such errors, you need to use only special tools, such as Viva64 or PC-Lint analyzers.

The next example is related to an implicit type cast, which also results in loss of significant bits. The fread function code reads from a file, but is incorrect when trying to read more than 2 gigabytes of data on a 64-bit system.

size_t __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp); size_t fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) ( int ret; FLOCKFILE(fp); ret = __fread(buf, size, count, fp); FUNLOCKFILE(fp); return (ret) ; )
The __fread function returns a size_t type, but the int type is used to store the number of bytes read. As a result, with large amounts of data being read, the function may return a different number of bytes than will actually be read. You can say that this is ignorant code for beginners, that the compiler will report such a type cast, and that in general such code is easy to find and correct. This is theoretical. But in real life, with large projects, everything can be different. This example is taken from the FreeBSD source code. The error was corrected only in December 2008! This is despite the fact that the first (experimental) 64-bit version of FreeBSD was released back in June 2003. Here is the source code before the fix:

http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdio/fread.c?rev=1.14

And here is the corrected version (December 2008):

http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdio/fread.c?rev=1.15

It's easy to make mistakes in code that works with individual bits. The next type of error is associated with shift operations. Let's look at an example:

ptrdiff_t SetBitN(ptrdiff_t value, unsigned bitNum) ( ptrdiff_t mask = 1
The above code works on a 32-bit architecture and allows you to set bits numbered 0 to 31 to one. After transferring the program to a 64-bit platform, there will be a need to set bits from 0 to 63. But this code will never set bits numbered 32-63. Please note that “1” is of type int and when shifted by 32 positions an overflow will occur, as shown in Figure 5. Whether the result is 0 (Figure 5-B) or 1 (Figure 5-C) depends on the compiler implementation.

Figure 5. A - Correct installation of the 31st bit in a 32-bit code; B,C - Error setting the 32nd bit on a 64-bit system (two behavior options) To correct the code, you need to make a constant “1” of the same type as the mask variable:

ptrdiff_t mask = ptrdiff_t(1)
Note also that uncorrected code will lead to another interesting bug. When setting 31 bits on a 64-bit system, the result of the function will be the value 0xffffffff80000000 (see Figure 6). The result of expression 1 size_t ArraySize = N * 4; size_t *Array = (size_t *)malloc(ArraySize); The main numbers that should be taken with caution when switching to a 64-bit platform are given in Table N4.

Table N4. The main magic values ​​that are dangerous when transferring applications from a 32-bit to a 64-bit platform In programs that process large amounts of data, errors associated with indexing large arrays may occur or eternal loops may occur. The following example contains 2 errors at once:

const size_t size = ...; char *array = ...; char *end = array + size; for (unsigned i = 0; i != size; ++i) ( const int one = 1; end[-i - one] = 0; )
The first error is that if the size of the processed data exceeds 4 gigabytes (0xFFFFFFFF), then an eternal loop may occur, since the variable "i" is of type "unsigned" and will never reach the value 0xFFFFFFFF. I specifically write that the occurrence is possible, but it will not necessarily happen. It depends on what code the compiler builds. For example, in debug mode the eternal loop will be present, but in the release code the looping will disappear, so the compiler will decide to optimize the code using a 64-bit register for the counter and the loop will be correct. All this adds to the confusion, and code that worked yesterday may suddenly stop working the next day. The second error is associated with passing through an array from end to beginning, for which negative index values ​​are used. The above code works in 32-bit mode, but when it is run on a 64-bit machine, on the very first iteration of the loop, the array will be accessed beyond the boundaries and the program will crash. Let's consider the reason for this behavior. According to the C++ language rule on a 32-bit system, the expression “-i - one” will be evaluated as follows (at the first step i = 0):
  1. The "-i" expression is of type unsigned and has the value 0x00000000u.
  2. The variable "one" will be expanded from type "int" to type unsigned and will be equal to 0x00000001u. Note: The type int is expanded (according to the C++ language standard) to type "unsigned" if it participates in an operation where the second argument is of type unsigned.
  3. A subtraction operation occurs, which involves two values ​​of type unsigned, and the result of the operation is 0x00000000u - 0x00000001u = 0xFFFFFFFFu. Note that the result is of unsigned type.
  4. On a 32-bit system, accessing an array at index 0xFFFFFFFFu is equivalent to using index -1. That is, end is analogous to end[-1]. As a result, the array element is processed correctly.
In a 64-bit system in the last paragraph the picture will be different. The unsigned type will be expanded to signed ptrdiff_t and the array index will be equal to 0x00000000FFFFFFFFi64. As a result, the array will be out of bounds. To fix the code, you need to use types such as ptrdiff_t and size_t. There are mistakes for which, in general, no one is to blame, but this does not stop them from being mistakes. Imagine that a long time ago in a distant galaxy (in Visual Studio 6.0) a project was developed that contained the CSampleApp class, which is a descendant of CWinApp. The base class has a virtual function called WinHelp. The heir overrides this function and performs the necessary actions. This is visually shown in Figure 7.

Figure 7. Working correct code that was created in Visual Studio 6.0 Then the project is transferred to Visual Studio 2005, where the prototype of the WinHelp function has changed, but no one notices this, since in 32-bit mode the DWORD and DWORD_PTR types are the same and the program continues to work correctly (Figure 8).

Figure 8. Incorrect, but workable 32-bit code The error is waiting to manifest itself on a 64-bit system, where the size of the DWORD and DWORD_PTR types is different (Figure 9). It turns out that in 64-bit mode the classes contain two DIFFERENT WinHelp functions, which is naturally incorrect. Please note that such traps can be hidden not only in MFC, where some functions have changed the types of their arguments, but also in the code of your applications and third-party libraries.

Figure 9. The error manifests itself in 64-bit code. Examples of similar 64-bit errors can be given and given. Those who are interested in such errors and want to learn more about them will be interested in the article “20 pitfalls of porting C++ code to a 64-bit platform.” As you can see, the stage of finding hidden errors is a non-trivial task, especially since many of them will appear irregularly or only on large input volumes of data. Static code analyzers are well suited for diagnosing such errors, since they can check the entire application code, regardless of the input data and the frequency of execution of its sections in real conditions. It makes sense to use static analysis both at the stage of porting an application to 64-bit platforms in order to find most errors at the very initial stage, and in the further development of 64-bit solutions. Static analysis will warn and teach the programmer to better understand the features of errors associated with the 64-bit architecture and write more efficient code. The author of the article is the developer of one of these specialized code analyzers, called Viva64. You can get acquainted with the tool in more detail and download a demo version from the website of the Software Verification Systems LLC company. To be fair, it should be said that code analyzers such as Gimpel PC-Lint and Parasoft C++Test have sets of rules for diagnosing 64-bit errors. But, firstly, these are general-purpose analyzers and the rules for diagnosing 64-bit errors are poorly represented in them. Secondly, they are more focused on the LP64 data model used in the Linux operating system family, which reduces their usefulness for windows programs that use the LLP64 data model. The step of finding errors in the program code described in the previous section is a necessary, but not sufficient step. No method, including static code analysis, provides a complete guarantee of detecting all errors, and the best result can only be achieved by combining different techniques.

If your 64-bit program processes more data than the 32-bit version, then you need to expand the tests to include processing of data larger than 4 gigabytes. This is the boundary beyond which many 64-bit errors begin to manifest themselves. Such tests can take an order of magnitude longer and you need to be prepared for this in advance. Typically tests are written in such a way as to process a small number of elements in each test and thereby be able to pass all internal unit tests, for example? in a few minutes, and automated tests (for example, using AutomatedQA TestComplete) in a few hours. A sorting function on a 32-bit system, if it sorts 100 elements, is almost guaranteed to behave correctly on 100,000 elements. But the same function on a 64-bit system can fail when trying to process 5 billion elements. The execution speed of a unit test can decrease by millions of times. Don't forget to factor in the cost of adapting tests when mastering 64-bit systems. One solution is to divide unit tests into fast ones (working with a small amount of memory) and slow ones, processing gigabytes and running, for example, at night. Automated testing of resource-intensive 64-bit programs can be built on the basis of distributed computing.