1

Creating a simple Console .NET Core app in Visual Studio 2019 will now default to AnyCPU platform (without Prefer 32-bit set, as it was with a .NET Framework app).

Yet if one toggles on the Prefer 32-bit, the results no longer respect the old logic, whereby an x86 executable would be generated, but instead an x64 is produced.

Some quick code to check:

Console.WriteLine("Initially allocated: {0} bytes", AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize);
int noNumbers = 1000000;
object[] objectArray = new object[noNumbers];
Console.WriteLine("Allocated in the end: {0} bytes", AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize);

Platform settings (in red) next to the code's output showing the quantity of memory allocated (in orange):

enter image description here

An element inside the object[] array will take 4 bytes on an x86 platform and 8 bytes on an x64 one. The output clearly shows this is x64 code. VMMap also confirms this find, based on the 64-bit virtual addresses visible within the process (green highlight):

enter image description here

One needs to specifically select x86 as platform to get a 32-bit executable:

enter image description here

Is 64-bit output code being generated when setting Prefer 32-bit to enabled in Visual Studio a deliberate change ?

Tested on Visual Studio 2019 16.5 on Windows 10 x64

Mihai Albert
  • 1,288
  • 1
  • 12
  • 27
  • Did you see https://stackoverflow.com/questions/12066638/what-is-the-purpose-of-the-prefer-32-bit-setting-in-visual-studio-and-how-does ? – Caius Jard Feb 20 '20 at 16:31
  • 1
    (Aside: You can check if your process is running as 64 bit more easily by accessing `Environment.Is64BitProcess`) – Matthew Watson Feb 20 '20 at 16:34
  • 5
    The assembly that's generated from you code really does have the option turned on. Something you can verify but running corflags.exe on the generated dll, note how the 32BITPREF flag is turned on. But the issue is that a DLL doesn't lock in the bitness of a process, it is the startup EXE that does it. Very different in .NETCore, it uses a host. Either dotnet.exe or a dedicated one that a VS project generates. The latter follows the platform selection. Dumpbin.exe /headers to see it, Machine type field. Well, that's a bit sloppy. – Hans Passant Feb 20 '20 at 16:50
  • @CaiusJard: I know that one form the research I performed a while back on how everything comes together, and posted here https://mihai-albert.com/2019/03/10/net-assembly-cross-bitness-loading/, but in .NET Core that no longer applies fully. – Mihai Albert Feb 20 '20 at 18:25
  • @MatthewWatson: I know that property, and even looked at the exact implementation (same link as in the other comment), but I'm on unfamiliar ground in .NET Core, hence I didn't want to be taken for a ride :) My reasoning was that VMMap won't lie. – Mihai Albert Feb 20 '20 at 18:27
  • @HansPassant: You're right. I missed that the output folder contains both an .exe and a .dll. So for the host process, the compiler just disregards the "Prefer 32-bit flag", as it simply doesn't matter any more - an AnyCPU-compiled assembly (regardless if it has the "Prefer 32-bit" flag set) can be loaded by a host process having any bitness. This also explains why the memory allocated from the very beginning is not 0, as my user code is sharing the AppDomain with the host process. But I do imagine some folks wondering why they ended up with a different .exe "product" than what they wanted – Mihai Albert Feb 20 '20 at 19:37

1 Answers1

3

As Hans Passant's comment indicated, Visual Studio will build (amongst other files) one .exe - which will disregard the Prefer 32-bit setting completely, and one .dll which will obey the setting (by toggling 32BITPREF).

I got in touch with Microsoft Support, whom in turn talked to the folks in the Visual Studio team. It turns out this is a known thing, and a GitHub issue already exists for removing the Prefer 32-bit altogether for .NET Core projects. In fact, Microsoft Support classified it as a bug.

I've also ran a few tests, and as it stands now, for a .NET Core Console App project, the various platform target settings in Visual Studio will determine the following results for the .exe and .dll respectively:

enter image description here

The full analysis around the file headers and the resulting process' bitness is here.

Mihai Albert
  • 1,288
  • 1
  • 12
  • 27