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".

Comments

  1. 16 Oct 2009 at 03:38

    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.

  2. 01 Jan 1999 at 00:00

    This thread is for discussions of Common Intermediate Language.

Leave a comment

Sign in or Join us (it's free).

Granville Barnettt My name is Granville Barnett I have been a programmer now for quite some time mainly focusing on .NET technologies (C#), C++ and general research (algorithms, compilers etc)
AddThis

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.

Want to stay in touch with what's going on? Follow us on twitter!