object used before assigned

T

tshad

In VS 2008,

I have an object, dbReader, that I get a warning saying that it is used
before it has been assigned a value.

That is correct.

Dim dbReader As SqlDataReader

and later:

Finally
If (Not dbReader Is Nothing) Then dbReader.Close()
End Try

Why is this an error?

Here I am testing to see if it is nothing, which it is (isn't it?) before
using it. The error is in the "if" test not the dbReader.Close().

Thanks,

Tom
 
J

Jack Jackson

In VS 2008,

I have an object, dbReader, that I get a warning saying that it is used
before it has been assigned a value.

That is correct.

Dim dbReader As SqlDataReader

and later:

Finally
If (Not dbReader Is Nothing) Then dbReader.Close()
End Try

Why is this an error?

Here I am testing to see if it is nothing, which it is (isn't it?) before
using it. The error is in the "if" test not the dbReader.Close().

Thanks,

Tom

I think the error is correct. The compiler is complaining that you
are testing dbReader before you have set it to anything.

You are assuming that dbReader is intialized to Nothing and therefore
the test is OK. While that is probably true, you should explicitly
set dbReader to Nothing on the Dim line. The compiler checks for
using before setting do not take into account the value that an
uninitialized variable has.
 
A

Armin Zingler

Jack Jackson said:
I think the error is correct. The compiler is complaining that you
are testing dbReader before you have set it to anything.

You are assuming that dbReader is intialized to Nothing and
therefore the test is OK. While that is probably true, you should
explicitly set dbReader to Nothing on the Dim line. The compiler
checks for using before setting do not take into account the value
that an
uninitialized variable has.

I think it is a bad practice to initialize a reference variable with Nothing
just to suppress the compiler warning. Maybe in the Try block he does use
dbReader.method and did forget to initialize the variable, and I mean
setting it to a real object and not to Nothing. It is almost like disabling
Option Strict to avoid warnings in lines that will never lead to an
exception in the particular case but can make us overlook errors in other
cases.

I also think that Is/IsNot comparisons of reference variables should not
lead to a compiler warning.


Armin
 
T

tshad

Jack Jackson said:
I think the error is correct. The compiler is complaining that you
are testing dbReader before you have set it to anything.

You are assuming that dbReader is intialized to Nothing and therefore
the test is OK. While that is probably true, you should explicitly
set dbReader to Nothing on the Dim line. The compiler checks for
using before setting do not take into account the value that an
uninitialized variable has.
That makes sense.

I think that scalars are set to their various defaults (ints are initialized
to 0, I belive). But reference variables are not (and that includes
strings - you get the same error if you enclose it in a block.

Thanks,

Tom
 
B

BobRoyAce

I also think that Is/IsNot comparisons of reference variables should not
lead to a compiler warning.

Armin

I have had this same issue many times. In fact, in one application,
this one warning occurs so many times, that I reach the max # of
warnings (like 102) and can't see the rest. It really bugs me too as
this seems to be a totally valid check. After all, dbReader is either
Nothing or it is not. As long as it has been Dim'd, this check should
be allowed WITHOUT a compiler warning, in my humble opinion.
 
T

tshad

Armin Zingler said:
I think it is a bad practice to initialize a reference variable with
Nothing
just to suppress the compiler warning. Maybe in the Try block he does use
dbReader.method and did forget to initialize the variable, and I mean
setting it to a real object and not to Nothing. It is almost like
disabling
Option Strict to avoid warnings in lines that will never lead to an
exception in the particular case but can make us overlook errors in other
cases.
The error is actually a warning not an error. And it does say that it could
lead to a runtime error. In C#, it is an error and won't let you continue
until you resolve it.

Sub Main()
Dim stemp As String
Dim stemp2 As String

Try

Catch ex As Exception
stemp = stemp2
End Try
End Sub

This is a warning because it could potentially cause a runtime error.

I don't think it is bad practice. A scalar is set to something, it is just
set by the compiler. It would be nice if the compiler would also set a
reference variable to nothing when defined as well. But there may be a
reason or a case where that may be a problem - not sure.

If you don't set it and goes to the Catch, you will probably get a runtime
error.

Why is setting the variable in the "try" any different than just setting it
to nothing to start with? Why would ever want the variable to be set to
garbage?

Thanks,

Tom

I also think that Is/IsNot comparisons of reference variables should not
lead to a compiler warning.

I agree, but it does.
 
H

Herfried K. Wagner [MVP]

Jack Jackson said:
I think the error is correct. The compiler is complaining that you
are testing dbReader before you have set it to anything.

You are assuming that dbReader is intialized to Nothing and therefore
the test is OK. While that is probably true, you should explicitly
set dbReader to Nothing on the Dim line.

I strongly disagree. In VB the statement 'Dim x As Foo' is semantically
equal to 'Dim x As Foo = Nothing' because VB implicitly initializes
variables of reference types with 'Nothing'. This is specified behavior and
I don't think there is any reason to make the programmer enter a rather
useless ' = Nothing', although the 'Dim x As Foo' statement already contains
this contract. Consequently I have disabled the warning and I consider it
flawed.
 
C

Chris Dunaway

I don't think it is bad practice. A scalar is set to something, it is just
set by the compiler. It would be nice if the compiler would also set a
reference variable to nothing when defined as well. But there may be a
reason or a case where that may be a problem - not sure.

Why is setting the variable in the "try" any different than just setting it
to nothing to start with? Why would ever want the variable to be set to
garbage?

The compiler doesn't set any values. They do not get set until
runtime.

Consider the following VB sub:

Private Sub SomeSub()
Dim s As String
Dim i As Integer

s = "Hello"
i = 123
End Sub

This code compiles to the following IL:

..method private instance void SomeSub() cil managed
{
.maxstack 1
.locals init (
[0] int32 i,
[1] string s)
L_0000: ldstr "Hello"
L_0005: stloc.1
L_0006: ldc.i4.s 0x7b
L_0008: stloc.0
L_0009: ret
}




Note the .locals init instruction. The init keyword sets a flag that
causes the JIT compiler to inject code initializing all local
variables before executing the sub. Thus, for all value types, the
corresponding memory is zeroed out and all reference types types are
set to null (Nothing in VB).

Although I agree that you should logically not assume the value of a
variable, you can assume in .Net that variables don't point to
anything bad when they are declared. They are initialized properly.

This information comes from the book "Expert .Net 2.0 IL Assembler",
By Serge Lidin, Apress

Cheers,

Chris
 
A

AMercer

I strongly disagree. In VB the statement 'Dim x As Foo' is semantically
equal to 'Dim x As Foo = Nothing' because VB implicitly initializes
variables of reference types with 'Nothing'. This is specified behavior and
I don't think there is any reason to make the programmer enter a rather
useless ' = Nothing', although the 'Dim x As Foo' statement already contains
this contract. Consequently I have disabled the warning and I consider it
flawed.

I agree with Herfried, and I have also disabled this warning.
 
A

AMercer

Where do you disable the warning?

In VS 2005, load your project, then go to Project, Properties, Compile, and
then disable condition "Use of variable prior to assignment". For other
versions of VS, it should be similar.
 
G

Göran Andersson

tshad said:
It would be nice if the compiler would also set a
reference variable to nothing when defined as well. But there may be a
reason or a case where that may be a problem - not sure.

Actually the variable is set to nothing when the method starts, and that
can potentially cause problems in some situations.

I guess that the warning has been introduced to prevent exactly that. It
wasn't there in earlier versions of VB.
 
G

Göran Andersson

Herfried said:
In VB the statement 'Dim x As Foo' is semantically
equal to 'Dim x As Foo = Nothing' because VB implicitly initializes
variables of reference types with 'Nothing'.

Not exactly. The variable is initialsed when the method starts, not
where the variable is declared. Consider:

For i As Integer = 1 to 10
Dim x As Integer
If i = 6 Then
x = 10
End If
Console.WriteLine(x)
Next

This would output:

0
0
0
0
0
10
10
10
10
10

If you change the line to:
Dim x As Integer = 0
It would output:

0
0
0
0
0
10
0
0
0
0

The warning is clearly intended to prevent situations like these.
 
C

Cor Ligthert[MVP]

Sloan,

And what does that help, beside not showing the warning.

Why should VB be used at the same low level as C#.

See the comments from Armin and Herfried about this.

Cor
 
C

Cor Ligthert[MVP]

Tshad,

I have tried your code, not any problem.

\\\\
Dim dbReader As System.Data.SqlClient.SqlDataReader
If (Not dbReader Is Nothing) Then dbReader.Close()
///

Are you sure that the declaration of the datareader is global or in the same
method?
(And not in the try block by instance)

Cor
 
T

tshad

Göran Andersson said:
Not exactly. The variable is initialsed when the method starts, not where
the variable is declared. Consider:

For i As Integer = 1 to 10
Dim x As Integer
If i = 6 Then
x = 10
End If
Console.WriteLine(x)
Next

This would output:

0
0
0
0
0
10
10
10
10
10
So you are saying in the above case it is initialized to 0 each time and
once set it stays set, but not in the one below?

Not sure I understand that. I would have thought that in both cases x would
be initialized to 0.

Thanks,

Tom
 
J

Jack Jackson

So you are saying in the above case it is initialized to 0 each time and
once set it stays set, but not in the one below?

Not sure I understand that. I would have thought that in both cases x would
be initialized to 0.

Thanks,

"Dim x As Integer" initializes x to zero when the method is entered.
The Dim statement does not change the value of x each time through the
loop.

"Dim x As Integer = 0" sets x to zero each time through the loop.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top