VB Migration Partner

KNOWLEDGE BASE - Language


Previous | Index | Next 

[HOWTO] Apply ByVal keyword to unassigned by-reference parameters

By default, VB6 passes arguments to methods using by-reference semantics: VB6 assumes a ByRef keyword unless an explicit ByVal keyword is used. Conversely, VB.NET and C# use by-value semantics by default, and of course VB Migration Partner correctly accounts for this difference.

Because of the default passing mechanism, it turns out that a lot of VB6 methods use by-reference semantics only because the original developer forgot to add an explicit ByVal keyword, as in the following simple example:

 
        Function Add(one As Short, two As Short, prod As Long) As Integer
            prod = one * two
            Add = one + two 
        End Function

VB Migration Partner includes a sophisticated code analysis engine that spots which ByRef parameters might be better rendered using by-value semantics. The engine recognizes parameters that are indirectly assigned by passing them to other methods or as arguments of language statements such as Input or Get#. The result of such analysis is included in the converted application in the form of special remarks, such as the following one:

 
        Function Add(ByRef one As Short, ByRef two As Short, ByRef prod As Integer) As Short
            ' UPGRADE_INFO (#0551): The 'one' parameter is neither assigned in current method 
            ' nor is passed to methods that modify it. Consider changing its declaration using 
            ' the ByVal keyword.
            ' UPGRADE_INFO (#0551): The 'two' parameter is neither assigned in current method 
            ' nor is passed to methods that modify it. Consider changing its declaration using 
            ' the ByVal keyword.
            prod = one * two
            Return one + two
	End Function

Notice that no warning is issued for the third parameter, because it is being assigned inside the method. Also, no warnings are emitted for parameters of methods that handle events or are followed by an Implements clause, because you can’t change the syntax of such methods.

You can prevent VB Migration Partner from emitting these special comments by disabling warning #0551:

        '## project:DisableMessage 0551

or by disabling all the warnings related to code analysis:

        '## project:DisableMessages CodeAnalysis

These warnings are quite valuable during the migration of large applications. Not only using the ByVal keyword where appropriate improves your code quality, often makes it run faster, and sometime avoids subtle issues that can occur in the converted VB.NET code.

For example, the value of a property is always passed with by-value semantics under VB6, even if the receiving parameter is marked with an implicit or explicit ByRef keyword. This means that the value of the property is never changed (even if the parameter is assigned inside the method) and the Property Set method for that property is never invoked. Conversely, value properties passed to methods honor the parameter’s passing mechanism under VB.NET: even if the parameter is never modified inside the method, the property’s Set block is invoked on exiting the method.

This detail is often a problem with objects in the ADODB library, because many properties of the Connection and Recordset objects become read-only when the object is open. Passing such properties to a ByRef argument doesn’t cause an error under VB6, but it throws a runtime exception under VB.NET, because the property’s setter method invoked on exiting the method. The ability to detect whether a ByRef parameter can be safely converted into a ByVal parameter allows developers to reduce the number of such issues.

You can use the UseByVal pragma to automatically insert the ByVal keyword for all the parameters that would otherwise generate the abovementioned warning - that is all the parameters that unnecessarily adopt the by-reference mechanism. This pragma can be defined at the project, class, method, or parameter level; its argument can be one of these three values: 

No: don’t add the ByVal keyword to all parameters are under the scope of the pragma. (This value is useful to cancel the effect of a pragma with a broader scope.)

Yes: add the ByVal keyword to all parameters that aren’t assigned inside the method and that aren’t explicitly marked with the ByRef keyword. (This is the value assumed if the pragma has no arguments.) 

Force: use the ByVal keyword for all the parameters that aren’t assigned inside the method, even if they are explicitly marked with the ByRef keyword. To understand how this pragma works, consider the following VB6 code:

 
        '## UseByVal
        Function Add(ByRef one As Integer, two As Integer, prod As Long) As Integer
            prod = one * two
            Add = one + two 
        End Function

and the VB.NET code that VB Migration Partner generates:

 
        Function Add(ByRef one As Short, ByVal two As Short, ByRef prod As Integer) As Short
        ' UPGRADE_INFO (#0551): The 'one' parameter is neither assigned in current method
        ' nor is passed to methods that modify it. Consider changing its declaration using
        ' the ByVal keyword.
            prod = one * two
            Return one + two
        End Function

Notice that the first parameter isn’t affected because it has an explicit ByRef keyword, but a warning is emitted nevertheless. If you had used the a ByVal Force pragma, then VB Migration Partner would have generated this VB.NET code:

 
        Function Add(ByRef one As Short, ByVal two As Short, ByRef prod As Integer) As Short
        ' UPGRADE_INFO (#0551): The 'one' parameter is neither assigned in current method 
        ' nor is passed to methods that modify it. Consider changing its declaration using 
        ' the ByVal keyword.
            prod = one * two
            Return one + two
        End Function
Previous | Index | Next 




Follow Francesco Balena on VB6 migration’s group on

LinkedIn





Read Microsoft Corp’s official case study of a VB6 conversion using VB Migration Partner.




Code Architects and its partners offers remote and onsite migration services.

More details




Subscribe to our free newsletter for useful VB6 migration tips and techniques.

newsletter



To learn more about your VB6 applications, run VB6 Analyzer on your source code and send us the generated text file. You will receive a detailed report about your VB6 applications and how VB Migration Partner can help you to quickly and effectively migrate it to .NET.

Get free advice



A fully-working, time-limited Trial Edition of VB Migration Partner allows you to test it against your actual code

Get the Trial




The price of VB Migration Partner depends on the size of the VB6 application, the type of license, and other factors

Request a quote




Migrating a VB6 application in 10 easy steps

Comparing VB Migration Partner with Upgrade Wizard

Migration tools: Feature Comparison Table

All whitepapers