Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Rhinorhino on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

"Call" statement 1

Status
Not open for further replies.

tg2003

IS-IT--Management
Joined
Feb 6, 2003
Messages
270
Location
IL
Hi,

I'm trying to understand what is that real meaning: When I call to a subroutine/function with "call" - Is it forked and run in concurrent mode, like a thread? Or the called sub/function is ran and when it stops it returns back to the main function?

I've read the MSDN help, but got no answers about it.

I'm asking it since I have a subroutine that if I call it with "call" - it doesn't works well, but if I omit the "call" - it works well.

Thanks in advance!
 
VB is single-threaded.

But threading isn't your issue. I'd guess that the real issue is the Call keyword. Have a look at the followingways of running a procedure, and see if it helps illutrate what is going on:
Code:
[blue]Option Explicit

Private Sub Command1_Click()
    myRoutine Text1
    myRoutine (Text1)
    Call myRoutine(Text1)
End Sub


Public Sub myRoutine(strTextControl As Variant)
    MsgBox TypeName(strTextControl)
End Sub[/blue]
 
strongm,

I just read this thing in Help:

If you omit the Call keyword, you also must omit the parentheses around argumentlist.

In your example you use the parentheses. Is it some undocumented feature? With more than one argument it is impossible, with one - possible, and it looks like it is treated differently. What is it? It looks like VB digests the parentheses - treats the whole thing like expression. But what will be the rule? What to expect?

Thank you!

vladk
 
As far as I know there is no difference in behaviour whether you use the Call statement or not. I would say that it is rarely used by the majority of VB programmers (just more code to type, so why bother).

tg2003 said:
Or the called sub/function is ran and when it stops it returns back to the main function?
When a sub/function ends then control always returns to the calling procedure.

You have not stated in what way your subroutine "doesn't work well" - so there is no way for us to diagnose. Posting your code and the error you get would help.

 
>there is no difference in behaviour whether you use the Call statement or not

There is a difference in the way expressions in parenthesis are interpreted. And my suspicion is that this is the route cause of the OPs problem

>In your example you use the parentheses. Is it some undocumented feature?

No, it isn't undocumented. Unless instructed otherwise (e.g. by the presence of the Call keyword), VB will try to evaluate an expression inside parenthesis; i.e. it is not an argument list (you may be more familiar with this use of parenthesis in more complex expressions when trying to control the order of evaluation)
 
StrongM - I tried your code and see what you mean. Of course, that is only a problem if the parameter is a Variant.

I'm sure the problem could be cleared up quickly if the OP posted his code.

 
The problems occur constantly when people are clueless. The real head scratcher for some seems to be:

[tt]SubName (Param1, Param2)[/tt]

... which won't compile.
 
The parentheses implies a ByVal parameter. Most of the parameters are byval anyway but sometimes the compiler doesn't know what to do so you have to help it by putting in parentheses.

The clueless example, well, I suffer from it too. I normally stick in a call instead of removing the parentheses. Takes 1 second to type "call " but quite a few more to remove the parentheses.
 
Sorry, but that's just ... wrong. Completely and utterly wrong. The parenthesis have nothing whatsoever to do with implying a ByVal parameter.


 
The combination of parenthese and call determine if the functions return value is discarded:

From help file
You are not required to use the Call keyword when calling a procedure.
1)However, if you use the Call keyword to call a procedure that requires arguments, argumentlist must be enclosed in parentheses.
2)If you omit the Call keyword, you also must omit the parentheses around argumentlist.
3)If you use either Call syntax to call any intrinsic or user-defined function, the function's return value is discarded.

That is why
X = msgbox("Do you want..",vbyesno)
returns a value
but
msgbox "Do you want..."

And (rule 1)
call mySubroutine(x,y)
or (rule 2)
mySubrounte x,y
 
Yes, there is that hack for calling an existing component's method. But in writing VBScript you declare ByVal parameters just as in VB6. Forcing expression evaluation by using parentheses does not "imply a ByVal parameter" at all. It simply coerces the parameter to a value having the proper type.

It may be necessary in places like that shown at the linked article but it isn't a substitute for declaring procedures properly in VBScript... or whatever language is being used. Normally if a parameter is declared ByRef it's for a reason: returning a value.

Defaulting to ByRef is unfortunate in a way, but defaulting to the most general case lets beginners get programs working easily. It isn't the best way to write programs though (see The "Works on My Machine" Certification Program).
 
I'm afraid that you are not understanding the article correctly. Which isn't all that surprising because the article is slightly misleading

In summary all it really says is that the parenthesis force the evaluation of the expression (exactly as they do in VB, and as we pointed out earlier in the thread).

This returns a new pointer to a new memory location containing the result of the evaluation. It is this new pointer that then gets passed to the sub, function (or COM object). One consequence of it being a new pointer is that it behaves like a ByVal parameter, in that making a change to the data pointed at by the new pointer clearly cannot change the data pointed at by the old pointer.

In other words, you have not actually changed the behaviour of VBS to support ByVal - you are still passing ByRef, it is just that you are passing a different variable ...

 
Thanks for the clarification
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top