Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there a difference in behaviour of an application built in VS 2010 v.s. VS 2012?

I was checking whether installing .NET 4.5 on our build machines changes the output IL image generated by VS 2010.

Since I know the behaviour of foreach has changed in .NET 4.5 to avoid issues due to Access to Modified closure, I chose a simple application that exhibited the behaviour.

  class Program
    {
        private static void Main(string[] args)
        {
            var contents = new List<Func<int>>();
            var s = new StringBuilder();

            int[] values = new int[] { 4, 5, 6 };

            foreach (int value in values)
            {
                contents.Add(() => value);
            }

            for (var k = 0; k < contents.Count; k++)
                s.Append(contents[k]());

            Console.WriteLine(s);
        }

VS 2010 output: 666

VS 2012 output: 456

I created a console application in VS 2010 and a console application with the same code in VS 2012 (both targeted .NET 4).

However, both the console applications exhibited different behaviours based on the IDE they were built with. In the build output, I checked that both had nearly similar build arguments. So I was wondering how the end executable exhibited different behaviour? .NET 4.5 is an in-place upgrade, so the compiler for both IDEs must be the same.

NOTE: I did have a look at a related question: Different LINQ Answer in VS 2010 and VS 2012 but it did not answer my question on why the executable behaviour differed.

EDIT 1: As mletterle mentioned, I did try building the code using the commandline in the output window of VS 2010 in a VS 2010 command prompt. The resulting output behaved as if it was built with VS 2012.

EDIT 2:

I am posting the output present in Output Window:

VS 2010: Build started 12/20/2012 11:04:56 PM.

CoreClean: Creating directory "obj\x86\Debug\". GenerateTargetFrameworkMonikerAttribute: Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files. CoreCompile:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /platform:x86 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /errorendlocation /preferreduilang:en-US /highentropyva- /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\Microsoft.CSharp.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Data.DataSetExtensions.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Data.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Xml.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\x86\Debug\TestConsoleApp.exe /target:exe /utf8output Program.cs Properties\AssemblyInfo.cs "C:\Users\105044960\AppData\Local\Temp.NETFramework,Version=v4.0.AssemblyAttributes.cs" _CopyAppConfigFile: Skipping target "_CopyAppConfigFile" because all output files are up-to-date with respect to the input files. CopyFilesToOutputDirectory: Copying file from "obj\x86\Debug\TestConsoleApp.exe" to "bin\Debug\TestConsoleApp.exe". TestConsoleApp -> C:\Users\105044960\Documents\Visual Studio 2010\Projects\TestConsoleApp\TestConsoleApp\bin\Debug\TestConsoleApp.exe Copying file from "obj\x86\Debug\TestConsoleApp.pdb" to "bin\Debug\TestConsoleApp.pdb".

VS 2012:

1>CoreClean: 1> Deleting file "c:\users\105044960\documents\visual studio 11\Projects\TestConsoleApp\TestConsoleApp\bin\Debug\TestConsoleApp.exe". 1> Deleting file "c:\users\105044960\documents\visual studio 11\Projects\TestConsoleApp\TestConsoleApp\bin\Debug\TestConsoleApp.pdb". 1> Deleting file "c:\users\105044960\documents\visual studio 11\Projects\TestConsoleApp\TestConsoleApp\obj\Debug\TestConsoleApp.csprojResolveAssemblyReference.cache". 1> Deleting file "c:\users\105044960\documents\visual studio 11\Projects\TestConsoleApp\TestConsoleApp\obj\Debug\TestConsoleApp.exe". 1> Deleting file "c:\users\105044960\documents\visual studio 11\Projects\TestConsoleApp\TestConsoleApp\obj\Debug\TestConsoleApp.pdb". 1>GenerateTargetFrameworkMonikerAttribute: 1>Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files. 1>CoreCompile: 1> C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702,2008 /nostdlib+ /platform:AnyCPU /errorreport:prompt /warn:4 /define:DEBUG;TRACE /errorendlocation /preferreduilang:en-US /highentropyva- /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\Microsoft.CSharp.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Data.DataSetExtensions.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Data.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Xml.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\TestConsoleApp.exe /target:exe /utf8output Program.cs Properties\AssemblyInfo.cs "C:\Users\105044960\AppData\Local\Temp.NETFramework,Version=v4.0.AssemblyAttributes.cs" 1>CopyFilesToOutputDirectory: 1> Copying file from "obj\Debug\TestConsoleApp.exe" to "bin\Debug\TestConsoleApp.exe". 1> TestConsoleApp -> C:\Users\105044960\Documents\Visual Studio 11\Projects\TestConsoleApp\TestConsoleApp\bin\Debug\TestConsoleApp.exe 1> Copying file from "obj\Debug\TestConsoleApp.pdb" to "bin\Debug\TestConsoleApp.pdb".

like image 756
Ganesh R. Avatar asked Dec 20 '12 16:12

Ganesh R.


People also ask

What is the special features of Visual Studio 2010 vs?

New Features and Enhancements in VS2010support for call hierarchy of methods. support for parallel programming and debugging. support for XSLT profiling and debugging. support for creating SharePoint applications.

Which version of Visual Studio is best?

Visual Studio 2022 is the best Visual Studio ever. Our first 64-bit IDE makes it easier to work with even bigger projects and more complex workloads.

What is the function of the Visual Studio Code application and how is it different from Visual Studio?

Visual Studio is an Integrated Development Environment, also known as an IDE. Visual Studio Code is a code editor. A developer can easily edit their code. VS is slower when it comes to performing across different platforms.

Why is Visual Studio better than VS Code?

If you need to collaborate with team members on development or debugging, then Visual Studio is the better choice. If you need to do serious code analysis or performance profiling, or debug from a snapshot, then Visual Studio Enterprise will help you. VS Code tends to be popular in the data science community.


1 Answers

Note: I removed much of my original response. It was answering the wrong question. A better response follows.

Ah, now I see what you're asking: "How does Visual Studio 2010 know to compile to C# 4 instead of C# 5 after .NET 4.5 is installed, even Visual Studio 2010 and Visual Studio 2012 use the same csc.exe and pass the same options to it?"

@mletterle But .NET 4.5 is an in place upgrade to .NET 4. So really there is only .NET 4 present on my machine. The only possibility is that the IDE has stashed away a hidden copy of .NET 4 compiler that I cannot see.

I'm not sure where you heard that or why you assumed that. .NET 4.5 is NOT an in-place upgrade. It is a different version of the tool. There will be differences. This is one of them.

Update 1:

Looks like we were using a different definition of "in-place" upgrade. My usage of "in-place" is "an upgrade that should have no discernible differences between versions." The definition given in the article you linked to uses it in a different way: "in place" in their usage is "uses the same CLR, but adds new libraries."

Since C# 5 is different than C# 4, that change is NOT "in place" in the usage I'm familiar with.

As a result, the difference is not the CLR you're targeting, but the language version you're using - the CLR is an "in place" upgrade (both the 4.0 CLR), but the language is not (C# 4 in VS2010, C#5 in VS2012.)

Update 2:

Within the .csproj file (which is actually an msbuild file managed by Visual Studio), there is an attribute that specifies the target framework. Projects made with Visual Studio 2012 have this by default:

<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>

Whereas projects in Visual Studio 2010 that target Version 4 look like:

<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>

This tells Visual Studio to set up the environment when building for one or the other target framework. While it looks like csc.exe is being invoked directly from a command prompt, it really isn't: the msbuild project is actually what's being processed, and it's happening in "Visual Studio"'s custom process environment.

I can only assume the specifics of what's happening, but likely after the upgrade, having the "TargetFrameworkVersion" attribute set to v4.0 returns the environment to v4.0 during the compilation of a project targeting v4.0. On the other hand, by invoking csc.exe from the command line without the environment set up by msbuild, it uses the "defaults" for its version (which is now defaulting to C# 5) giving you the new C# 5 behavior even though you're using the VS 2010 command prompt. When you invoke the build via MSBuild, though, it knows how to return to the original C# 4 environment for the duration of the build (since MSBuild is part of the .NET tool chain, too.)

like image 161
Robert P Avatar answered Oct 21 '22 01:10

Robert P