PDA

View Full Version : Wierd VB6 behaviour


monoman
24th July 2008, 05:14 AM
I have a subroutine:

Private Sub ChangeVariable(ByRef thisVariable as Boolean)
thisVariable = True
End Sub
If I call it like this, with brackets:

Dim Ok as Boolean
ChangeVariable (Ok)The variable Ok is not changed to True

However, if I call it like:

ChangeVariable OkIt is changed to True.

Why does this happen?

ETA: I expect it to be changed in both cases

Bindamel
24th July 2008, 05:35 AM
I can't tell you WHY it doesn't, but it is an expected result:



[Call] name [argumentlist]

Remarks
You are not required to use the Call keyword when calling a procedure. However, if you use the Call keyword to call a procedure that requires arguments, argumentlist must be enclosed in parentheses. If you omit the Call keyword, you also must omit the parentheses around argumentlist.

monoman
24th July 2008, 08:05 AM
I can't tell you WHY it doesn't, but it is an expected result:

Hmm.. In that case, a compile error should be thrown. Bag of *****!

ETA: An error is thrown if there's > 1 parameter. eg:

DoThis ("parm1", "parm2")But not for this:

DoThis ("parm1")This must be an old bug but I couldn't find anything on the web.

aggle-rithm
24th July 2008, 08:28 AM
This must be an old bug but I couldn't find anything on the web.

I agree completely. VB6 is an old bug.

GodMark2
24th July 2008, 04:23 PM
When you put parenthesizes around a variable, the compiler calculates the value of whatever is inside the parens, and sends that to the function.

For multiple variables, the equivalent statements would be:
Dim Ok as Boolean, NAK as Boolean
MySub Ok, NAK
MySub (Ok), (NAK)

In the second case, you're passing the result of a calculation, not a reference to the actual variable. The calculation in this case is "copy this value". VB expects a reference to a boolean (rather than the value of a boolean) and so it automatically passes the reference to the result of that calculation. But that calculation is transient, and, while it is changed properly, the result is lost as soon as the statement is no longer executing.

The multi variable case helps to show that, to the compiler, "(Ok)" is quite different from "Ok". Unfortunately, the single variable case it looks the same to us humans as passing the variable without the parens.

Now, if VB were consistent about this, it wouldn't cause problems, but:
Dim Ok as Boolean, NAK as Boolean
Call MySub (Ok, NAK)Is an allowable construct, and the single variable version:
Dim Ok as Boolean
Call MySub (Ok) Doesn't look like it should be different fromDim Ok as Boolean
MySub (Ok)

But it is. The presence, or absence, of the "Call" keyword tells the compiler to interpret two otherwise indistinguishable lines in completely different ways.

Earthborn
24th July 2008, 05:23 PM
It is indeed a very old bug -- or feature, Microsoft would say. Good old QBasic does it in exactly the same way. In all statements that do not require parentheses, the parenthesis are interpreted the way they are in normal calculations. In 3*(2+5), the 2+5 in calculated first and then multiplied by 3. Everything inbetween parentheses is calculated first, it is just that the arguments of a SUB for some reason also need to be in parentheses if the SUB is called with the CALL statement, a statement you might prefer to forget about.