fantini.name

just wasting bandwidth...

Against VB.NET Syntax

Allowing to omit the return statement in function definitions is pointless

Published on 10 May 2012

waste of time

In my humble opinion, a good compiler should -among other things- do its best to raise every possible error at compile-time. This approach usually helps avoiding run-time errors, which is just what every programmer wants. This is the reason why I generally like strongly-typed programming languages more than weakly-typed ones. And this is also one of the reasons why I like the Java syntax more than the VB.NET syntax.

In my limited VB.NET experience, I get the impression that the philosophy behind VB.NET is to “annoy” the programmer as little as possible at compile-time… or at least to allow him to be annoyed as little as possible (see the Option Strict Off statement, or the many options to disable various warnings/errors during compilation). And I have the conviction that this is always a bad idea.

A few days ago, a colleague of mine called me to report a strange bug in one of our software systems, a print/conversion server engine that prints and converts CAD drawings on a dedicated host. He was messing with the XML configuration file when the program stopped printing drawings with strange error messages. The problem was due to this wrong VB.NET function definition:

Public Function GetJobMaxTryCount() As Integer
	Try
		Integer.Parse(GetOptionParam("JobMaxTryCount"))
	Catch ex As Exception
		Return 3
	End Try
End Function

This function retrieves the value of a specific option (<JobMaxTryCount>) from the XML configuration file. During my early investingation, while I was talking on the phone with my colleague and digging in the source code looking for the problem, I actually came through this function, but at a quick glance I didn’t notice anything strange and I went on. So I had to setup the print server on my dev box to try to reproduce the problem. Then I debugged the program and finally noticed what was wrong: the function was missing its Return statement in the Try block. So, when my colleague specified the option <JobMaxTryCount> in the configuration file (by default this tag was initially omitted), the call to Integer.Parse stopped throwing an exception and the function stopped returning 3 (the default value for this option when omitted). But lacking the Return call in the Try block, the function was always returning 0, no matter what he specified for the option in the XML file. And since 0 is a invalid value for this option, the program was behaving in that strange way.

My first reaction was disbelief: why wasn’t the compiler complaining about such a function definition? Then I checked the value for the Function/Operator without return value compiler option in my project: it was set to Warning (the default value in VS2008). Nevertheless I was not receiving any warning from the compiler. The reason is that such a syntax is just correct in VB.NET: if you define a Function that returns an Integer value, you are allowed to omit the Return statement in one or more code paths; in those code paths, the function just returns 0.

I know that VB.NET is not the only language that allows this implicit return statement in integer functions (C is another example). Anyway, my simple question is: why?!? What’s the point in allowing the programmer to not explicitly return a value?

It took me more 3 hours to investigate, reproduce, and fix the problem. I am well aware that this waste of time is my fault: it was me to write the buggy function. But the Java compiler would have refused to compile an int function defined in that way (with a missing return statement error message). So, would I have been using Java instead of VB.NET, I would have saved more than 3 hours of work.

This is one of the (many) reasons why I like Java more than VB.NET.

Fabrizio Fantini 10 May 2012

blog comments powered by Disqus