Skip to main content

Understanding (ref)erences !!!

Let us take a look at the following piece of code:-
public void Operate(IList iList2)
{
iList2 = new List();
iList2.Add(1);
iList2.Add(2);
iList2.Add(3);
}

public static void Main()
{
IList iList= new List();
iList.Add(10);
Operate(iList);
Console.WriteLine(iList[0].ToString());
}
Be thinking about what would the above program print to the console ? And that is what we are going to talk about in this post - simple but subtle.

I saw this code at CodeProject discussions. The author was confused with why was the program printing 10 instead of 1. I am writing about this since the 'gotcha' was not highlighted in the discussion.

So we passed the reference 'iList' to the function which is supposed to make it point to the 'List' that it creates and so must be printing 1. Well, a C++ programmer knowing how to program in C# would have said 'Gotcha' already. A reference (in C#), equivalent to a pointer in C++, is an entity that stores the address of an object in heap and accesses it using this address. So when we pass a reference (by value) to a function, then we are passing this address value. That is captured in another 4 byte variable local to that function; so creating assigning inside the function will make iList2 point to newly created object - iList and iList are two different reference pointing to the same object. So if you want to transmit the effect of the changes you make to the List inside the function, pass it by reference - use ref keyword.

Now the fun part !!! Let us try writing the same stuff in C++:-
// This function will not alter the source pointer
void Operator(IList* pList)
{
pList = new List();
pList->Add(1);
pList->Add(2);
pList->Add(3);
}

// This function will affect the source; similar to using ref in C#
// 1) const IList*& pList - Can make pList point elsewhere but cannot modify the existing object
// 2) IList* const &pList - pList cannot point to anywhere else but can modify the existing object
void Operator(IList*& pList)
{
pList = new List();
pList->Add(1);
pList->Add(2);
pList->Add(3);
}
Hope that was fun !!!
Post a Comment

Popular posts from this blog

Passing CComPtr By Value !!!

This is about a killer bug identified by our chief software engineer in our software. What was devised for ease of use and write smart code ended up in this killer defect due to improper perception. Ok, let us go!CComPtr is a template class in ATL designed to wrap the discrete functionality of COM object management - AddRef and Release. Technically it is a smart pointer for a COM object.void SomeMethod() { CComPtr siPtr; HRESULT hr = siPtr.CoCreateInstance(CLSID_SomeComponent); siPtr->MethodOne(20, L"Hello"); }Without CComPtr, the code wouldn't be as elegant as above. The code would be spilled with AddRef and Release. Besides, writing code to Release after use under any circumstance is either hard or ugly. CComPtr automatically takes care of releasing in its destructor just like std::auto_ptr. As a C++ programmer, we must be able to appreciate the inevitability of the destructor and its immense use in writing smart code. However there is a difference between …

out, ref and InvokeMember !!!

When I was working on the .NET reflection extravaganza thing that I explained in my previous column, i learnt one another interesting thing, that is about the Type.InvokeMember. How will pass out or ref parameters for the method invoked using Type.InvokeMember ? If you are going to invoke a method with the prototypeint DoSomething(string someString, int someInt);then you would use InvokeMember like this:-object obj = someType.InvokeMember("DoSomething",
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
null,
this,
new object[] {"Largest Integer", 1});or use some variables in the new object[] {...}. But what do you with the args if DoSomething takes out or ref parameters ?int DoSomething(out string someString, ref int someInt);Something like this will not work string someText = string.Empty;
int someInt = 0;
object obj = someType.InvokeMember("DoSomething",
BindingFlags.Public | BindingFlags.NonPublic …

Offering __FILE__ and __LINE__ for C# !!!

THIS POST USES SYNTAXHIGHLIGHTER AND HAS ISSUES RENDERING CODE ONLY IN CHROME
Not the same way but we could say better.
Visual Studio 2012, another power packed release of Visual Studio, among a lot of other powerful fancy language features, offers the ability to deduce the method caller details at compile time.
C++ offered the compiler defined macros __FILE__ and __LINE__ (and __DATE__ and __TIME__), which are primarily intended for diagnostic purposes in a program, whereby the caller information is captured and logged. For instance, using __LINE__ would be replaced with the exact line number in the file where this macro has been used. That sometimes beats the purpose and doesn't gives us what we actually expect. Let's see.

For instance, suppose you wish to write a verbose Log method with an idea to print rich diagnostic details, it would look something like this.
void LogException(const std::string& logText, const std::string& fileName, …