Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Dealing with 32-bit, 64-bit and Any CPU Compilation Options in .NET

4.70/5 (17 votes)
12 Dec 2016CPOL4 min read 33K  
Ever wondered why Visual Studio IDE provides 3 options for compilation - x86, x64 and Any CPU? As part of this article, I hope to shed some light on this.

Ever wondered why Visual Studio IDE provides 3 options for compilation - x86, x64 and Any CPU?
While most are aware of these options, many still lack clarity on the significance of these options (including me earlier in my career). So, as part of this article, I hope to clear some of these doubts.

Windows OS has evolved over the years, right from the time it started out as a 16-bit OS, then transitioned to 32-bit (x86) and more recently to 64-bit (x64).

Why Would You Use a 64-bit OS over 32-bit?

To understand this, let's understand the capabilities of both 32-bit and 64-bit CPUs.

  • 32-bit CPU

    • Address pointer size is 32 bits -> can access 2^32 (4,294,967,296) discrete addresses.
    • This allows a program to make a data structure in memory up to 4 GB in size.
  • 64 bit CPU

    • Address pointer size is 64 bits -> can access 2^64 (18,446,744,073,709,551,616) discrete addresses.
    • This allows a program to make a data structure in memory up to 16 Exabytes in size.
  • Main advantages (64-bit over 32-bit)

    • Process on a 64-bit CPU can work with a larger set of data compared to 32-bit CPU (only constrained by physical memory).
    • A 64 bit integer makes arithmetic or logical operations using 64 bit types such as C#’s long faster than one implemented as two 32 bit operations.
  • To summarize, for all practical purposes…

    • Applications that use large amounts of memory, like Image and video editing software, 3D rendering utilities, and video games will make better use of a 64-bit architecture and operating system, especially if the machine has 8 or even 16 GB of RAM that can be divided among the applications that need it.

Understanding the Behaviour of 32-bit, 64-bit and Any CPU compiled PE Files

  • On a 32-bit machine:

    • Any CPU: Runs as a 32-bit process, can load Any CPU and x86 assemblies, will get BadImageFormatException if it tries to load an x64 assembly.
    • Any CPU-32-bit preferred (default): Same as Any CPU.
    • x86: Same as Any CPU.
    • x64: BadImageFormatException always.
  • On a 64-bit machine:

    • Any CPU: Runs as a 64-bit process, can load Any CPU and x64 assemblies, will get BadImageFormatException if it tries to load an x86 assembly.
    • Any CPU-32-bit preferred (default): Runs as a 32-bit process, can load Any CPU and x86 assemblies, will get BadImageFormatException if it tries to load an x64 assembly.
    • x86: Runs as a 32-bit process, can load Any CPU and x86 assemblies, will get BadImageFormatException if it tries to load an x64 assembly.
    • x64: Same as Any CPU.

Any CPU-32-bit Preferred

This is a new option introduced starting with .NET 4.5 and Visual Studio 11. It is a new subtype of Any CPU and is also the default compilation option in the IDE.

You can check this in the project properties as shown in the screenshot below …

Visual Studio project properties default compilation option

How 32-bit PEs Work on 64-bit Architectures?

  • Generally, only 32-bit PEs can be loaded into a 32-bit process, and only 64-bit PEs can be loaded into a 64 bit process.
  • When a 32-bit PE is launched on a 64-bit OS, it runs in the “WOW” (Windows-32 on Windows-64) to present an illusion of a 32-bit operating system to the process.

Why Was the Any CPU Compilation Option Introduced?

  • Now before 64-bit Windows OS was introduced, there was just the 32-bit PEs (of course, we are not considering 16-bit OS in this discussion) and hence during compilation, these PEs were marked as 32-bit and there was no ambiguity.
  • With the introduction of 64-bit Windows OS, a decision had to be made – should the binaries be marked as 32-bit or 64-bit by default?
  • Technically speaking, managed binaries have no hard CPU dependency – they could be either 32 or 64 bit.
  • However, there was a way required to reuse .NET libraries from both 32-bit and 64-bit processes. For this, the OS loader support was extended to support architecture-neutral PE files (Any CPU).
  • In case of Any CPU PEs, the OS loader decides how to initialize the process. On 64-bit OSs, they are run as 64-bit processes, and on 32-bit OSs, they are run as 32-bit processes.

Hope this post helped clarify a few things!!
I’ll also touch upon how to identify the architecture affinity of a PE in a future post.

Abbreviations

  • PE: Process Executables (EXEs and DLLs)

References

The post Dealing with 32-bit, 64-bit and Any CPU compilation options in .NET appeared first on Sundeep Kamath's blog.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)