Whidbey and 64-bit Compiler Options

There’s something that’s been nagging me for weeks about Visual Studio Whidbey and .NET Framework 2.0 and it relates to the 64-bit support that’s built in for the two Intel 64-bit solutions and the AMD 64-bit solution.

You can see it in a new command line option to the C Sharp Compiler, the VB Compiler, the Assembly Linker and (I daresay) the C++ compiler and J# compilers. The option looks like this;

/platform:[x86|x64|Itanium|anycpu]

Now, the nagging voice in my head has kept saying to me;

What the heck is that option all about, isn’t one of the benefits of CIL that we compile once and then deploy to any platform where we will compile the CIL into real code either at installation time or by using JIT at runtime.

So, I went off to try and do some digging to satisfy my own curiosity about what that flag means. In doing so, I found this excellent blog that belongs to Josh Williams where he’s written a lot of detail about the 64-bit CLR.

There’s something in this article that I hadn’t really thought about and hence this blog post. I knew that when you take a 32-bit application to 64-bit Windows it will run using the new WOW64 compatibility layer which leaves it executing as a 32-bit process and this should be pretty inexpensive on the x64 chips (AMD/Intel) and slightly more expensive on the Itanium (Intel).

However, I’d naively assumed that any .NET code written in CIL would automatically run as a native 64-bit application on a 64-bit OS and as a 32-bit application on a 32-bit OS and that this is what you’d always want so there would be no need for any of these new compilation flags.

But that’s not the case and John highlights it really well. Essentially, when your application runs on a 64-bit box it is either entirely a 64-bit application or it’s entirely a 32-bit application. That is, all the DLLs that your application loads need to be consistent in their 32-bit/64-bit nature. You cannot load up a 64-bit application which then loads an old 32-bit DLL and vice versa.

This then impacts .NET code. If you’re writing a .NET application that calls out to some DLL via P/Invoke then if that DLL is only available as a 32-bit DLL then your code is only going to be able to run on a 64-bit machine as a 32-bit application. Your application cannot magically become 64-bit if it depends on DLLs that you don’t have a 64-bit version of. If your application is pure managed code then you should be ok and, similarly, if you’ve made P/Invokes out to DLLs that you do have 64-bit versions of (e.g. Windows DLLs) then, again, you should be ok as long as you made judicious use of System.IntPtr and so on.

So, with all that said John gives a great explanation of what those /platform flags really mean.

x86: I’m a 32-bit binary. Always run me as a 32-bit binary (on 64-bit that means run in WOW64).

x64: I’m a 64-bit binary for x64 only. Always run me as a 64-bit binary (on 32-bit or Itanium that means "Doesn’t run")

Itanium: I’m a 64-bit binary for Itanium only. Always run me as a 64-bit binary (on 32-bit or x64 that means "Doesn’t run").

anycpu: Run me anywhere. On 32-bit run as 32-bit. On 64-bit run as 64-bit.

You’re going to use that x86 option when you’ve got .NET code that depends on code that you don’t have a 64-bit version of. So, you’ll always run 32-bit regardless of what the platform is.

The anycpu option is the default option. You’d expect that the vast majority of .NET applications are going to be happy with anycpu in that they won’t have dependencies on code that is not available in a 64-bit environment (i.e. the application will either be entirely managed or where it’s not entirely managed it will only have extra dependencies on API’s that are part of Windows and so are available in 64-bit mode).

I’m struggling at the moment to see scenarios where you’d specify x64 or Itanium. I guess it might be for scenarios where you’ve got a dependency on some code that you just don’t have a Itanium or x64 version of and so you don’t want to run on that other platform at all.

That’s it – John’s article is the real information here and I’ve just summarised it to make myself feel better about what those flags are for. No more "nagging doubts".