Library tutorials & articles
Common Intermediate Language
C++ vs C#
In this part we will look at the differences between what the C++/CLI compiler generates and that the C# compiler generates with regards to MSIL.
We won't be creating any MSIL applications this time, but rather we will be analyzing the MSIL.
C++/CLI
I really like C++/CLI, it brings the best of both worlds - managed and unmanaged and allows the developer to jump in and out of each world seamlessly. I would like to point out that C++/CLI and C++ (and C) are more tailored towards system development rather than application development which are more C# and VB.NET space.
Note: the next version of C++ will include a garbage collector that will be turned off by default.
For this part I'm going to use two examples, a Person class that will be the same in C# as C++ although in C++ I will use get/set methods instead of properties (although properties are get_ and set_ methods after the compiler has worked it's magic).
Person.h
#pragma once ref class Person { public: Person(void); Person(System::String^ firstName, System::String^ lastName); System::String^ GetFirstName(void); void SetFirstName(System::String^ firstName); System::String^ GetLastName(void); void SetLastName(System::String^ lastName); virtual System::String^ ToString(void) override; private: System::String^ m_firstName; System::String^ m_lastName; };
Person.cpp
#include "StdAfx.h" #include "Person.h" using namespace System; Person::Person(void) { m_firstName = System::String::Empty; m_lastName = System::String::Empty; } Person::Person(System::String^ firstName, System::String^ lastName) { m_firstName = firstName; m_lastName = lastName; } System::String^ Person::GetFirstName(void) { return m_firstName; } void Person::SetFirstName(System::String^ firstName) { m_firstName = firstName; } System::String^ Person::GetLastName(void) { return m_lastName; } void Person::SetLastName(System::String^ lastName) { m_lastName = lastName; } System::String^ Person::ToString(void) { return m_firstName + " " + m_lastName; }
We will create a similar Person class in C# now then compare the MSIL generated for a few methods.
C#
using System; namespace MsilTest { public class Person { private string _firstName; private string _lastName; public Person(string firstName, string lastName) { _firstName = firstName; _lastName = lastName; } public string FirstName { get { return _firstName; } set { _firstName = value; } } public string LastName { get { return _lastName; } set { _lastName = value; } } public override string ToString() { return _firstName + " " + _lastName; } } }
The comparison
We will look at the MSIL generated first for the ToString() method.
C++/CLI
.method public hidebysig virtual instance string ToString() cil managed { // Code size 30 (0x1e) .maxstack 2 .locals ([0] string V_0) IL_0000: ldarg.0 IL_0001: ldfld string Person::m_firstName IL_0006: ldstr " " IL_000b: call string [mscorlib]System.String::Concat(string, string) IL_0010: ldarg.0 IL_0011: ldfld string Person::m_lastName IL_0016: call string [mscorlib]System.String::Concat(string, string) IL_001b: stloc.0 IL_001c: ldloc.0 IL_001d: ret } // end of method Person::ToString
C#
.method public hidebysig virtual instance string ToString() cil managed { // Code size 28 (0x1c) .maxstack 3 .locals init ([0] string CS$1$0000) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldfld string MsilTest.Person::_firstName IL_0007: ldstr " " IL_000c: ldarg.0 IL_000d: ldfld string MsilTest.Person::_lastName IL_0012: call string [mscorlib]System.String::Concat(string, string, string) IL_0017: stloc.0 IL_0018: br.s IL_001a IL_001a: ldloc.0 IL_001b: ret } // end of method Person::ToString
There's not much difference at all between the C++/CLI and C# implementation - the C# compiler tells the CLR it wants 3 slots on the stack max because it uses the Concat method which takes 3 args thus 3 strings are pushed onto the stack prior to the method call where as the C++/CLI implementation calls the Concat method twice using the 2 arg version, hence the maxstack being 2.
Note: both binaries are debug releases and are not optimized.
In the C# MSIL there is a nop instruction this is used for debugging, e.g. breakpoints, and stands for "no operation".
Related articles
Related discussion
-
Binary Studio | software development outsourcing Ukraine
by shane124 (4 replies)
-
Making the conversion from Visual Basic to .NET
by JimiJ (1 replies)
-
Seeking developers for Montreal Office
by mazen_kt (1 replies)
-
Chart insertation in a windows form...
by pdhanik (1 replies)
-
Point of Sale Developers: Hardware & C# SDK
by ManiGovindan (7 replies)
Related podcasts
-
A Practical Look at Silverlight 2 Part 1
Now that Silverlight 2 is at the Olympics and making a big splash, we wanted to explore this fascinating technology more. Microsoft Silverlight 2 is a cross-browser, cross-platform, and cross-device plug-in for delivering the next generation of .NET based media experiences and rich interactive ap...
Events coming up
-
Nov
18
15 Minutes of Fame
Dresher, United States
This is a yearly tradition. We select 10 of the favorite speakers from monthly meetings, code camps, and hands on labs. Each one does a 15 minute talk on their favorite .NET technology. This is our 10th anniversary so we plan a gala event with special prizes and refreshments.
can u please do sove this program.......and send it at my e-mail add...rach_dizon2002@yahoo.com 1. create a program called MathInteger.java that presents a menu tothe user nwith choices for (1) adding first n integer (2) multiplying the first n integer and (3) quitting.use do while loop.Also switch statement for option 1 and 2. 2. create a program called SumIntegers.java allows the user to enter exactly 10 n positive integers.If the user accidentally enters negative integer the program should use continue statement to skip the entry.
!--removed tag-->This thread is for discussions of Common Intermediate Language.