3

I have an array witch I pass to a function by reference to sort it. However, seems like the array is passed byval. Can anyone solve what's the problem? (Also sort workarounds accepted)


1) The script below passes an array by-reference to the sort function.

2) Sort function outputs the sorted array values.

3) The script outputs the sorted array values. However they are not sorted.


The script outputs:

300,200,100,,

100,200,300,


'declare variables
mitta(1) = 1
mitta(2) = 2
mitta(3) = 3

sort(mitta)  ' see the function below

' show variables
For i = 1 To 3
    response.write mitta(i) & ","
next

' sort function
function sort(byref a)
    dim num,i,j,temp
    num = ubound(a)+1
    For i = 0 To num - 1
       For j = i + 1 To num - 1
          If a(i) < a(j) Then
             temp = a(i)
             a(i) = a(j)
             a(j) = temp
          End If
       Next
    Next

    ' show sorted variables
    For i = 0 To num - 1
        response.write a(i) & ","
        a(i) = 0
    next
end function
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
viljun
  • 370
  • 3
  • 12
  • How do you know it's not based on your samples? It's already sorted. Also you don't need the variable num. Since you're adding 1 to `ubound(a)` and then using num - 1 it makes sense just to use `ubound(a)`. Also, you're probably getting dumped from your function in the last iteration of the j loop. When i = `num - 1` (the end of the array), j will attempt to be `i + 1`. This is out of the bounds of the array and `a(i) < a(j)` will fail. – Joel Etherton Apr 19 '11 at 11:18

3 Answers3

7

By wrapping mitta in parentheses in the function call sort(mitta), you're actually passing it by value, despite the function declaration. From http://blogs.msdn.com/b/ericlippert/archive/2003/09/15/52996.aspx:

The rules are

3.1) An argument list for a function call with an assignment to the returned value must be surrounded by parens: Result = MyFunc(MyArg)
3.2) An argument list for a subroutine call (or a function call with no assignment) that uses the Call keyword must be surrounded by parens: Call MySub(MyArg)
3.3) If 3.1 and 3.2 do not apply then the list must NOT be surrounded by parens.

And finally there is the byref rule: arguments are passed byref when possible but if there are “extra” parens around a variable then the variable is passed byval, not byref.

Now it should be clear why the statement MySub(MyArg) is legal but MyOtherSub(MyArg1, MyArg2) is not. The first case appears to be a subroutine call with parens around the argument list, but that would violate rule 3.3. Then why is it legal? In fact it is a subroutine call with no parens around the arg list, but parens around the first argument! This passes the argument by value. The second case is a clear violation of rule 3.3, and there is no way to make it legal, so we give an error.

See also the MSDN reference for ByRef and ByVal Parameters. Instead, you should call sort either with:

sort mitta

or:

Call sort(mitta)
Cheran Shunmugavel
  • 8,319
  • 1
  • 33
  • 40
3
call sort(mitta)

That's it, just add the keyword call. Complete reference is available here.

BTW, your code has problems. The arrays are 0 based.

Salman A
  • 262,204
  • 82
  • 430
  • 521
0

When you pass an object as parameter, you are passing a pointer to the object, not the object itself (this apply to all languages I know). So it does not matter if you pass it ByVal or ByRef, because by definition you are always passing a pointer (a reference to the object)

Eduardo Molteni
  • 38,786
  • 23
  • 141
  • 206