11

I saw this nice image here. I learned that all the compilers that support .net language convert the source code to CIL format. Now Microsoft is never bringing in .NET for all the operating system by writing a CLR for all operating systems. Then why keep such an intermediate code format and a CLR to execute that CIL. Is that not an headache to deal with. Why did Microsoft choose be like this ?

EDIT This kinda architecture has its price. It will reduce the performance, wouldn't it ? Java does this to maintain platform independence, for what reason .NET do it ? Why not keep a simple plain C like compiler. Any way will also require a compiler to convert the code to CIL if I need to add up any new language, the only difference it would make is the target language. Tat's all.

  • 3
    Because it is easier to write compilers to CIL. And it is easier to write one CIL to native compiler than a compiler to each and every language to native. – Oded Sep 23 '13 at 15:09
  • 9
    @ratchetfreak: that may be a reason for MS for not porting the CLR to other platforms, but its not a reason for having a CLR in the first place (which does actually make a port easier, so your argument sound just like MS bashing, sorry) – Doc Brown Sep 23 '13 at 15:24
  • 12
    Also downvote for 'M$', what is this, 1998? – Alan B Sep 23 '13 at 16:19
  • 3
    Eric Lippert discusses this (starting on the 3rd paragraph; the first 2 paragraphs are about Roslyn). The short answer is that Oded's comment and Telastyn's answer are right; you only need to code <Number of operating systems>+<Number of languages> compilers instead of <Number of operating systems>*<Number of languages> compilers. – Brian Sep 23 '13 at 21:10
  • 3
    @busy_wait: The referenced page mentions a few downsides. For example, "the configuration information in two applications might result in different binding decisions for the same dependent assembly." Generating on the fly avoids these issues. This implies that the compilation really needs to be done after the app is distributed (and in fact, NGEN must be run on each target machine; it cannot be run by the distributor). – Brian Sep 23 '13 at 21:50
29

Because they only need to write one compiler for C# to CIL - which is the hard part. Making an interpreter (or more often, Just-In-Time compiler) for the CIL per platform is relatively easy compared to writing a compiler from C# to (per platform) executable code.

Beyond that, the runtime can handle anything that compiles to CIL. If you want a new language (like F#) you only have to write one compiler for it and you auto-magically get all the platform support for things .NET supports.

Oh, and I can take a .NET dll and run that on windows or on linux via Mono without recompilation (assuming all of my dependencies are satisfied).

As for performance, it's debatable. There are "pre-compilers" essentially that take the CIL and make native binaries. Others argue that just-in-time compilers can make optimizations that static compilers simply cannot. In my experience, it depends a lot on what your application is doing and what platform you're running it on (mostly how good the JITer is on that platform). It's extremely rare for me to run into a scenario where .NET wasn't good enough.

  • "interpreter"`? I thought always MS provides only a JITter? – Doc Brown Sep 23 '13 at 15:27
  • 1
    @DocBrown - eh, yes - misnomer on my part. Fixing. – Telastyn Sep 23 '13 at 15:34
  • +1, can you add up a little bit of explanation for my edit so that I can accept this answer – vikkyhacks Sep 23 '13 at 15:36
  • High-performance runtimes often combine an interpreter and a JIT compiler (mixed-mode execution). I'm not sure about .NET, but many Java VMs use this approach. – Cyanfish Sep 23 '13 at 17:56
  • 2
    @busy_wait: All sorts of things. Method inlining, copy propagation, removing unnecessary code, converting multiplications/divides to shifts, other arithmetic operations using readonly fields. Traditional compilers can do some of these optimizations but only when they can be detected by static analysis. By contrast, a jitter can find out at runtime that (for example) a section of code isn't doing any useful work because the objects or variables it modifies aren't referenced anywhere else. I'm no expert on jitters but it's basically a question of the power of dynamic vs. static analysis. – Aaronaught Sep 24 '13 at 0:23
14

.NET has an intermediate language (CIL/MSIL) and platform-specific implementations of a platform-independent runtime (CLR) for the same reason Java does. Microsoft intended C# to directly compete with Java, and it does, on the OSes that Microsoft targets (its own).

The advantages, even though .NET is only supported on Windows platforms (or other OSes that have a .NET workalike like Mono/Linux), are similar to Java:

  • Managed Memory Runtime - Unlike unmanaged C/C++, C#/VB.NET developers don't have to worry about strictly controlling object lifetime. Like Java, the CLR has a garbage collector that automatically frees objects in the heap that leave scope. While this may seem minor to someone used to unmanaged runtimes, it has the extreme secondary advantage of discouraging the "black magic" of pointer arithmetic that is so common in C/C++.
  • Platform Independence - Windows Vista and Windows 7 work differently from Windows XP. Windows 8 works still differently. Windows Mobile versions including Windows 8 Mobile work differently again. Different hardware, different architecture, different capabilities. While the target environment does still matter to a .NET developer, the amount of specialized knowledge is far reduced compared to what has to be known to build a compatible C/C++ program for all of these OSes. A C# dev gets a lot more for free.
  • Web application support - I haven't yet seen a client-facing, server-scripted web application written from the ground up in C++. The web server, sure, Apache, ISS, they all typically run against an unmanaged runtime for speed/efficiency reasons. However, C++ is not a language used for building web applications. C# is (as is Java). It was designed from the ground up to support the next generation of Microsoft's ASP paradigm. This is code designed to run in a sandbox; which sandbox (the ASP.NET plugin to ISS or the "desktop" CLR) is relatively unimportant.
  • Language/runtime independence - A C++ compiler takes C++ source code and produces assembly code for one processor architecture using one machine language. To support a different architecture and/or machine language, a completely new compiler must be written (and a completely new set of runtime libraries must be compiled). A C# compiler takes C# source code and produces CIL, which the hardware-specific JITer translates to machine code. The same JITer can translate any CIL program no matter what the source language (and there are several; C#, VB.NET, F#, and a host of "Iron" language ports like IronHaskell, IronRuby, IronLisp, etc). The same compiler can turn one language into CIL that any JITer can run, no matter the hardware. This reduces the amount of work that must be redone from scratch for every new language or platform supported by the .NET Framework.
  • Focus on "correct" code - For C++ devs, there are a lot of "right" ways to do something, depending on what's most important; memory efficiency, CPU efficiency, hardware independence, OS independence, etc. Code can look drastically different when each of these is the priority. C# was designed by a group that took to heart the conceptual lessons of Fowler and his colleagues (who were working to reform code design within the C++ community by teaching object-oriented principles to a community that largely moved up into it from C), as well as the practical lessons learned by the languages that came before (including Java, and its near-fanatical obedience to the almighty Object, when a good old C++-style function pointer would do the job much more cleanly and not be any less object-oriented).

For antitrust reasons, MS is careful not to be seen "interfering" too heavily in other major platforms like Android, Mac OSX/iOS and Linux; however, it does indeed have teams developing for all three of these platforms. There's an MS-developed version of Office for OSX, there are numerous applications including Office interop apps for iOS and Android, Skype (now a Microsoft product) runs on Linux, and Microsoft has even been seen contributing to the Linux kernel (primarily in a virtualization mindset).

  • 1
    "I haven't yet seen a client-facing, server-scripted web application written from the ground up in C++." - where do you put CGIs of days of old? My very first web applications (as trivial as they were) were 100% C. Back then (mid '90s) it was easier to write a .c and .h for doing the standard work in cgi (the 'scripting' languages were just emerging on the scene too). – user40980 Sep 23 '13 at 21:14
  • hm... CGI, CGI... I think I heard of it, but I'm with KeithS, I'm yet to actually see one :) – DXM Sep 23 '13 at 21:22
  • @DXM the old model of dynamic content was for the web server fork a process and put things in standard places (query params and the like went in specific environment variables) - the Common Gateway Interface. The output of that process was then sent back as the content. In the old days, it was easier to find a programmer who knew C or C++ rather than perl or python (and sh was very clunky for such work). – user40980 Sep 23 '13 at 22:35
  • 1
    Don't underestimate the importance of the similarity with Java. Sun had just sued MS for their port of the JVM and won some legal points (stupidly, IMHO). CIL and the CLR are inspired by that, and you will notice that J# is as close as it can be to Java without triggering further legal actions. A huge difference is that the CLR is language agnostic. You really can write a program in a mix of C#, F#, and J# if that is what is needed. Just try to mix Java with libraries in other languages and get a stable program. – RBerteig Sep 23 '13 at 23:58
  • 1
    But interop between MSIL and native code is both reasonably well defined and just works. And apparently was expected to just work by design, and by the attitudes of the user community. – RBerteig Sep 24 '13 at 21:02
12

The Windows OS is available for different CPU types, today mostly x64, x86, Intel, ARM.

CIL/CLR is independent from that hardware platform - these differences are "abstracted away" by the IL execution environment. For example, a .NET assembly compiled for "any CPU" can typically executed on Win64 as a 64 bit process, and Win32 as a 32 bit process, without the need of providing different executables.

Moreeover, the CIL allows metadata to be stored in assemblies which is not easily possible with native DLLs (it is possible, of course, MS did this before with COM components, but that technology was never as easy to handle as .NET components). That makes creation of software components a hell lot simpler and is the foundation of reflection / introspection in all .NET languages.

  • Just to add a bit to this, not only do they allow different CPU types but even different version(Core i3/i5/i7) and vendors (Intel vs. AMD) within the same CPU type (all x64 for example) might have different sets of assembly instructions which JIT compiler would be able to take advantage off – DXM Sep 23 '13 at 16:12
  • 2
    @DXM: and you know the JIT does actually? Or is this more a hypothetical thing? – Doc Brown Sep 23 '13 at 16:22
  • At least a MSDN blog claims the JIT compiler does do that (or did, 8 years ago). – user7043 Sep 23 '13 at 17:03
  • @DocBrown: Obviously I don't have any reference material on-hand, but I thought I remembered reading something about this long time ago. Thanks delnan, for finding the link. It would make sense since we know chip manufacturers like to add their own instructions on top of standard x86-x64 so if the machine can take advantage why wouldn't it? – DXM Sep 23 '13 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.