The is a very simple mechanism where a compiler thing can do a 64 bit EXE file that will convert itself into 32 bit when appropriate at run time.
Not exactly. the logic still has to be written; the Sysinternals tools use a particular method to make it a single executable. All that logic is part of the codebase, not something baked in by the compiler.
As you said, that should work unless the programmer was making assumptions about the size of pointers.
Not exactly... it will work but only in VM languages like .NET or Java. in C and C++, where pointer arithmetic is commonplace, a lot of dependency on pointers being a specific size can be added without realizing it. For example, various built-in types can change size. Of course this can be fixed with typedefs, but at the same time, there is the issue of file formats with regard to those data types.
basically, from a programming standpoint, a migration has several pitfalls:
First, a lot of applications rely on other applications created by other vendors; for example, solutions created using VBA. At that point regardless of how well your application is written, the application you are working with might not work well as a 64-bit application, or there might be compatibility issues between the 32-bit version of that application and the 64-bit version. Prime example? an Excel application that accesses eBay’s Web service for the purpose of automating sales. The 64-bit version of Excel
isn’t completely compatible with the 32-bit version of Excel, so you encounter a host of unexpected problems with your application upgrade. It’s easy to miss a problem such as using a 32-bit number to hold a 64-bit handle, truncating it, and causing a crash because the handle isn’t valid.
Data access- which I touched on before, can introduce all sorts of problems to the migration of an existing codebase. One prevalent issue is that a 64-bit application that writes 32-bit values will write then as 64-bit values, because the data type used in the codebase is a different size. So when a 32-bit application accesses that data, it only gets 32-bits out of a full 64 bits, and when it saves it back it essentially truncates what the 64-bit version wrote, assuming it understands it at all. In most cases, the entire database becomes mangled before anybody even notices there is a marshaling problem. Sometimes it can be more subtle. Example being managed code such as Java or .NET calling into the Operating System. To the managed code, the value still appears to be 32-bits (because it is supposed to be platform independent), but to the operating system that handle is really 64-bits and is treated as such, introducing a subtle, difficult to reproduce once every while crash or intermittent issue. What ends up happening is one of the devs has to trace every data transaction to ensure what you think you're writing as data is what you're actually writing.
This issue extends of course to disk storage, as well as in memory. Many devs learn the hard way that data structes that work fine in a 32-bit environment- or even a 16-bit environment- no longer work in a 64-bit environment. There can be many causes, but the primary one is that a 64-bit environment packs data into structures differently, which can break assumptions made in various locations of the code as to how the structure is laid out in memory. even if all the data elements are the same size, they aren't in the same location in memory that might be expected. Of course this issue is exacerbated by the more widely known, basic issue regarding pointer size.
Add into this the common practice of using "clever" code (which typically only proves how stupid you are... but, I digress) using things like bitshifts and bit-wise OR and ANDs to achieve tasks that they wouldn't typically be used for. Many of these "tricks" rely on the size of the value being manipulated to be 32-bits, an assumption which of course fails when those values are suddenly 64-bits wide.
There is far more to the migration than merely dealing with bigger pointers. For new code it is of course easy to take account and avoid; but many developers are dealing with codebases that are several years old and it is unlikely that 64-bit was even considered during initial development.