Почему при передаче элемента массива в функцию через ParamArray в функцию приходит varpointer? - PullRequest
0 голосов
/ 04 сентября 2018

Я заметил странность в VBA при использовании ParamArray и прохождении через него элементов массива. В некоторых случаях в функцию поступает не значение элемента массива, а указатель var. (Excel 2016, 32-разрядная версия).

После некоторого усердия я обнаружил, что определение функции как вариантного массива - в сочетании со списком параметров в сочетании с ParamArray - кажется, откуда происходит непредвиденное поведение, но я не вижу никаких возможных причин почему это так.

Поведение возвращается к нормальному, когда:
1) переменная r убрана в объявлениях функций
2) b объявлено с Dim b()
3) функция возвращает Variant, а не Variant()

Я понимаю, что это довольно эзотерический вопрос, и кажется, что его можно контролировать различными способами, но есть ли какое-либо объяснение, объясняющее это поведение?

Sub Variantarraybug()
   Dim b: b = [{1, 2, 3}]

   Debug.Print farray1(2, b(1))(0)
   Debug.Print Application.WorksheetFunction.Sum(farray1(2, b(1)))
   Debug.Print Join(farray1(2, b(1)), " ")

   Debug.Print farray2(2, b(1))(0)
   Debug.Print Application.WorksheetFunction.Sum(farray2(2, b(1)))
   Debug.Print Join(farray2(2, b(1)), " ")
   Debug.Print  VarPtr(b(1)), VarPtr(b(2))
End Sub

Function farray1(r, ParamArray plop()) As Variant
   farray1 = Array(plop(0), 3)
End Function
Function farray2(r, ParamArray plop()) As Variant()
   farray2 = Array(plop(0), 5)
End Function

Результат в окне отладки:

 1  
 4  
1 3  
 1  
 6  
358808368 5  
 358808368     358808384 

Примечание 1: Насколько я понимаю, функция VarPtr возвращает ячейку памяти начального адреса памяти, необходимой для этой переменной. Здесь он используется только для демонстрации того, что неожиданное число ( 358808368 ), которое было замечено функцией farray2, на самом деле является адресом этого элемента.

Примечание 2: Это происходит независимо от того, как вы генерируете массив (например, b=array(1,2,3), b=[1,2,3] и т. Д.) И как объявляется b (b, b(1 to 3), так далее.). Однако если вы объявите b с Dim b(), неожиданное поведение исчезнет. (В этом случае вы не можете напечатать VarPtr(b), так как VarPtr не может принимать переменные массива.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...