The Artima Developer Community
Sponsored Link

.NET Buzz Forum
Late bound overload resolution and structures

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Paul Vick

Posts: 783
Nickname: paulv
Registered: Aug, 2003

Paul Vick is a Tech Lead on Visual Basic at Microsoft Corp.
Late bound overload resolution and structures Posted: Oct 7, 2004 11:26 PM
Reply to this message Reply

This post originated from an RSS feed registered with .NET Buzz by Paul Vick.
Original Post: Late bound overload resolution and structures
Feed Title: Panopticon Central
Feed URL: /error.aspx?aspxerrorpath=/rss.aspx
Feed Description: a blog on Visual Basic, .NET and other stuff
Latest .NET Buzz Posts
Latest .NET Buzz Posts by Paul Vick
Latest Posts From Panopticon Central

Advertisement

I was just reviewing some notes I made about updating the language specification and I came across this little gem: What do you think the following code does?

Option Strict Off
Structure MyStruct
Public MyField As Integer

Public Sub Mutate(ByVal x As Byte)
MyField = x
End Sub

Public Sub Mutate(ByVal x As Short)
MyField = x
End Sub
End Structure

Module Module1

Sub Main()
Dim o As Object = 5S
Dim s As MyStruct

s.MyField = 10
s.Mutate(o)
MsgBox(s.MyField)
End Sub

End Module

Yes, that's right, it prints 10. Why? Well, it has to do with how we handle overload resolution and loose-typing.

When we were originally coming up with the rules for overload resolution, we noticed a particular problem with loosely-typed code (that is, code that doesn't explicitly state the types of its variables). Because all the variables in a loosely-typed program are typed as Object, there are a lot of places where the regular overload resolution rules fall down. Take the example above: if you follow the normal rules of overload resolution, the call to s.Mutate is ambiguous. That's because the argument type is Object and the two parameter types are Byte and Short. Object has narrowing conversions to both Byte and Short, so we can't actually choose between them.

However, we thought, at run-time all values become strongly typed. So even though the variable may be statically typed as Object at compile-time, if we defered the overload resolution to run-time, we could probably resolve the overloading correctly. (I should point out again that this only applies to loosely-typed programs: in a strongly typed program, you'd just insert a cast to resolve the ambiguity.) So we added a special "loosely typed overload resolution rule" to handle this situation: if overload resolution produces an ambiguous result solely because of narrowing conversions from Object, then we defer the resolution until run-time. Or, in other words, we make the call late bound. This isn't such a bad thing because if you're doing loosely-typed programming, by definition you're going to be doing a lot of late binding anyway.

OK, so all is well and good, no? Well, not exactly. You see, the problem in the above situation is that to make the call to Mutate late-bound, we have to call some helper functions at run-time. And those helper functions take the target of call as a value typed as Object (since you can late-bind against any type). Which means that we have to cast the target of the call to Object. Which means that, since MyStruct is a structure, we have to box the value. Which means that the target of the call is no longer the stack location indicated by s, but instead some heap location where we boxed the value to. Which means that Mutuate changes the heap location instead of the stack location, and so the change is lost when the method returns.

This is an unfortunate subtle interaction between two features. The good news is that you really only will get into trouble when mixing strongly-typed with loosely-typed code. If, in the example above, you'd typed s as Object and assigned it a new instance of MyStruct, everything would have worked as expected because the structure would always have been boxed. On the other hand, if you turn Option Strict On, the above example will give you an error on the overloaded call to Mutate and will require you to resolve the ambiguity with a cast. So the chance of anyone running into this is thankfully remote. 

Read: Late bound overload resolution and structures

Topic: Podcasting Catches Fire Previous Topic   Next Topic Topic: Determining if a T-SQL variable is in a range of values

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use