Function Warning - Null Reference

  • Thread starter Thread starter Stephany Young
  • Start date Start date
Stephany said:
Return hh & "h " & mm & "m " & ss & "s"

I don't know how much background you have in VB. I'll assume not much.
To clarify:
"Function 'Dec2hms' doesn't return a value on all code paths." means
that a function might not be returning a value along one of its
possible paths of execution, and that a line of code that calls the
function could get a Null Pointer from the function. In VB and VB.NET,
A Sub (Subroutine) is a procedure which never returns a value. A
Function is a procedure that MUST return a value.
To return a value from a function, use the keyword Return followed by
the value or variable that is being returned.
Placing
Return hh & "h " & mm & "m " & ss & "s"
at the end of the function (right above "end function") should fix the
problem.
 
Thanks Stephany,

I understand your explanation and what the warning is indicating. In order
to remove the warning I would need to ensure the function does not return a
null pointer. Is there a better syntax available giving a more complete
solution?

My experience comes from VBA and I have just started out in VB and .NET. The
structure and syntax is what I am trying to understand. The best way for me
is to have some good books, try converting some VBA code and visit these
newsgroups. Just wished I started 3 years ago.

Regards
 
First of all, let's get some terminology straight. The warning states:

Warning 1 Function 'Dec2hms' doesn't return a value on all code paths. A
null reference exception could occur at run time when the result is used.

Nowhere does it mention 'null pointer', it mentions 'null reference' and
that is a completely different animal.

For the sake of your own sanity it is important to remember that, for the
purpose of your learning curve, 'VB doesn't do pointers'.

Without going into the why's and wherefore's, some types in .NET are called
value types. These include String, Integer, DateTime and Boolean among
others. These are usually implemented as a Structure rather than as Class. A
type implemented as a Class is usually called a reference type.

In general, you can assing Nothing to a variable of a reference type and
that variable is considered to be unassigned.

When you assign Nothing to a variable of a value type, then, behind the
scenes, the default value for that particular value type is substituted. The
default value for a String is String.Empty, the default value for an Integer
is 0, the default value for a DateTime is 01/01/0001, the default value for
a Boolean is False and so on and so forth.

In VBA, you would have written a function something like:

Function Test() As String

Test = "Hello World!"

End Function

and you called it using something like:

x = Test()

The single statement in the function assigned a string as the return value
of the function. It used a syntax where you assigned the value to the name
of the function.


If you had coded the function as:

Function Test(ByVal flag As Boolean) As String

If value Then Test = "Hello World!"

End Function

Then the value "Hello World!" would be returned only if the parameter (flag)
had a value of True. If it had a value of false then, the function 'fell
through the logic' or 'took another path' and, because the type of the the
return value was declared as string, an empty string was automaticallty
returned.

In VB.NET, exactly the same thing applies, BUT, at compile time, you get a
warning that, at least one of the paths through the logic does not explicity
set a return value.

To avoid this warning, I recommend that you get into the habit of always
explicity setting return values from functions, like:

Function Test(ByVal flag As Boolean) As String

If value Then
Return "Hello World!"
Else
Return String.Empty
End If

End Function

Note that in Vb.Net, we assign the return value via the keyword 'Return'
rather than assigning to the function name. It is functionally equivalient
to, but probably more efficient:

Test = "Hello World!"
Exit Sub

The real difference is that 'Return <value>' assigns the return value and
returns immediately, all with a single statement.
 
I am getting the following warning for the below function. I understand what
it means but how do I handle a null reference? Then how do I pass the
resulting value?

Regards



Warning 1 Function 'Dec2hms' doesn't return a value on all code paths. A
null reference exception could occur at run time when the result is used.
G:\Project Development\Visual Studio
2005\Projects\Ascension\Ascension\SwephConversions.vb 64 3 Ascension


' Convert decimal hours to hours/minutes/seconds

Public Function Dec2hms(ByVal x As Decimal) As String

Dim hh As Int32, mm As Int32, ss As Decimal, remainder As Decimal

'Dim x a decimal, hh as integer

hh = CType(x, Integer)

remainder = (x - hh)

mm = CType((remainder * 60), Integer)

remainder = ((remainder * 60) - mm)

ss = Int(remainder * 60)

remainder = ((remainder * 60) - ss)

If remainder >= 0.5 Then

ss = ss + 1

Else

ss = ss

End If

hms = hh & "h " & mm & "m " & ss & "s"

End Function

The problem is that you are not returning a value at all that I can see.
Which means that the value of the function will always be a null reference.
There are two, ways to return a value from a function in vb.net. One, is the
same as the old vb way - and that is to assign the value to the function name:


Public Function Dec2hms As String
....

Dec2hms = hh & "h " & mm & "m " & ss & "s"
End Function

The other, prefered way is to use the Return statment:

Public Function Dec2hms As String
....

Return hh & "h " & mm & "m " & ss & "s"
End Function

Now, to avoid these kind of warnings, you just need to make sure that there is
a return along all normal code paths.... I personally like to structure code
so that there is only one exit point, so that often leads to code that looks
something like:

Public Function SomeFunc As Boolean
' i chose to default to a failure, but that
' can change based on what is easier and makes
' more sense for the method
Dim success As Boolean = False

' do cool stuff that might change the value of success

Return success

End Function

HTH,
 
Hi Stephany,

Excellent explanation, this makes sense to me;

If value Then
Return "Hello World!"
Else
Return String.Empty
End If

Thanks, regards
Terry
 
Thanks Tom,

Good points. I will use the Return statement for the reasons given by
Stephany in his post, but setting an initial value for the Return may be
advantageous and less code lines. In your example setting success=False
(fail) is similar to how I checked for successful table updates in VBA, True
would mean there were no errors and Commit, False caused a Rollback. In my
function I'll set hms as empty.

I'll give both suggested methods a trial just for the coding experience.

As an aside, in VBA it was necessary to explicitly check the value of a
boolean variable 'If myBool = True Then...'. This is because there can be
the occasional problem encounted if you used 'If myBool Then...', it's a VBA
thing. Any such problems with VB.NET?

Regards
Terry
 
Great summary; however there are a couple of mistakes in what you say which
I should point out.

Stephany Young said:
Without going into the why's and wherefore's, some types in .NET are
called value types. These include String, Integer, DateTime and Boolean
among others. These are usually implemented as a Structure rather than as
Class. A type implemented as a Class is usually called a reference type.

String is NOT a value type; it is a reference type. String is what's called
an immutable reference type (once created, the string will never change
value).
In general, you can assing Nothing to a variable of a reference type and
that variable is considered to be unassigned.

When you assign Nothing to a variable of a value type, then, behind the
scenes, the default value for that particular value type is substituted.
The default value for a String is String.Empty, the default value for an
Integer is 0, the default value for a DateTime is 01/01/0001, the default
value for a Boolean is False and so on and so forth.
Because of the above, the default value for an uninitialised string is
Nothing (null reference) not String.Empty. The difference is quite
important, as you will get a NullReferenceException if you attempt to do
anything with a string before it is assigned.

Hope this clarifies,

Nick Hall
 
Yes. Absolutely!!!

Because I never declare a string variable without initialising it, it easy
to forget some of the nuances of the String class when it is unitialised and
treat it as if it were a value type, which of course is quite wrong.

I stand reminded.
 
The 'VBA thing' as you put it was primarily caused by the use of the variant
data type.

I recommend that, in ALL your VB.NET projects, you set Option Explicit and
Option Strict. Doing so will highlight places where such a problem is likely
to occur.

If you code:

Dim myBool As Boolean

If myBool Then
...
End If

then you won't run into that problem.

FYI and in case you want to upset me in the future, I'm a 'her', not a
'his'. ;)
 
FYI - Option Explicit is already on, by default in VB .NET. But, yes do
turn Option Strict on to make VS.NET force you to write more bullet-proof
code.
 
I am getting the following warning for the below function. I understand what
it means but how do I handle a null reference? Then how do I pass the
resulting value?

Regards



Warning 1 Function 'Dec2hms' doesn't return a value on all code paths. A
null reference exception could occur at run time when the result is used.
G:\Project Development\Visual Studio
2005\Projects\Ascension\Ascension\SwephConversions.vb 64 3 Ascension


' Convert decimal hours to hours/minutes/seconds

Public Function Dec2hms(ByVal x As Decimal) As String

Dim hh As Int32, mm As Int32, ss As Decimal, remainder As Decimal

'Dim x a decimal, hh as integer

hh = CType(x, Integer)

remainder = (x - hh)

mm = CType((remainder * 60), Integer)

remainder = ((remainder * 60) - mm)

ss = Int(remainder * 60)

remainder = ((remainder * 60) - ss)

If remainder >= 0.5 Then

ss = ss + 1

Else

ss = ss

End If

hms = hh & "h " & mm & "m " & ss & "s"

End Function
 
Nick,

There is in my idea a mistakes in your reply to Stephanie.

She is not writing a string *is* a value. She writes a string is *called* a
value type. That is often done, a string acts almost completely as a value
type.

As you wrote is a string is declared it has no reference and Is therefore
Nothing, as soon however that it is used in an operation it get a value and
= than Nothing. This standard assignment is only with strings.

Cor
 
I have to disagree Cor. I think it was clear the Stephany was indicating
that a String is a Value Type and, as Tom pointed out, it is not. I don't
know how you could read the statement below and confuse her description as
anything but examples of what value type and reference types are. Also,
given her tone about how important terminology is, I think it was clear she
wasn't being anything esle but direct.
 
Sorry about that Stephany, should have guessed. Thanks for the help, and
slapped wrist :-)
Regards

Terry
 
Scott,

I am sorry Scott, but in my idea is the main from Stephanie's message true.

I find it an insult to tell that a so long regular as Stephany does not know
that a string is a reference type, therefore I find that she wrote is very
correct measuring what she would write in advance.

Cor
 
Well, you are certainly entitled to your opinion. I'm not insulting anyone,
I'm just responding to what she wrote. She may have known that a String is
a reference type, but that's not at all what she wrote. And since the OP
may not be aware of Stephany's "regular" contributions to the group (I'm not
sure I recall seeing her messages before either), the OP needs the correct
info.
 
Cor:

Thank you for your concern but I am a big girl and quite capable of sticking
up for myself. Please note that I corrected my mistake about 3.5 hours
before your post.

Scott:

Yes you are correct. I did state that a string is a value type but you will
note that when it was pointed out that I was incorrect I, effectively,
apologised for that mistake (just over 24 hours before your post).

In General:

If anyone is going to have a go at me, please have the courtesy to spell my
name correctly.
 
Scott,

As you all are than so concerned about the correct name for the string,
which in my opinion acts in many cases as a value, why than not for the
DateTime structure which Stephany calls in the same sentence a value (AFAIK
are the string and the datetime both the two exceptions from the standard
rules)?

Cor
 
See my message to Scott .

As extra
For me it is standard to shift the y at the end of names in pluriform mode
to ie, I will try not to do that again for your name, I don't remember me
from what language I have that.

You are probably the last which one who I will help in this newsgroup.
Moreover, I can not put one character in a message or there comes a scary
comment from you.

If I reference in a thread to you, than I do that to make the explanation
easier.

Cor



..
 
Back
Top