Jump to content

Passing parameter ByRef, previously passed ByRef


Recommended Posts

Hi,

I have the following problem:

Func Function1(Const ByRef $parameter)
Function2($parameter)
EndFunc

Func Function2(Const ByRef $parameter)
...
EndFunc

Au3Check returns error

Func Function1(ByRef $parameter)
Function2($parameter)
EndFunc

Func Function2(Const ByRef $parameter)
...
EndFunc

Doesn't work properly.

My question is: the $parameter is a large array. I cannot pass it ByValue. What's the alternative?

Edited by TheGeneral
Link to comment
Share on other sites

THis works for me:

Global $array[3] = ['a', 'b', 'c']

function1($array)

Func Function1(Const ByRef $parameter)
    Function2($parameter)
EndFunc

Func Function2(Const ByRef $parameter)
    ConsoleWrite($array[0] & @CRLF)
    ConsoleWrite($array[1] & @CRLF)
    ConsoleWrite($array[2] & @CRLF)
EndFunc

Link to comment
Share on other sites

Try that:

main()

Func main()
   Local $array1[3], $array2[3]
   Function1($array1)
   Function2($array2)
EndFunc

Func Function1(Const ByRef $parameter)
    Function2($parameter)
EndFunc

Func Function2(Const ByRef $parameter)
    ConsoleWrite($parameter[0] & @CRLF)
    ConsoleWrite($parameter[1] & @CRLF)
    ConsoleWrite($parameter[2] & @CRLF)
EndFunc
Edited by TheGeneral
Link to comment
Share on other sites

First off, what's the error message you're getting? Second, what are you actually doing with the array when either passing it to function2 or inside function1 after 2 is done?

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

First off, what's the error message you're getting? Second, what are you actually doing with the array when either passing it to function2 or inside function1 after 2 is done?

The error message is this one:

C:UsersThe_GeneralDocumentsTIM.au3(304,72) : ERROR: _Array2D_BinarySearch() previously called with expression on Const ByRef param(s).
Func _Array2D_BinarySearch(Const ByRef $avArray, $vValue, $iColumn = 0)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:UsersThe_GeneralDocumentsTIM.au3(68,61) : REF: first call to _Array2D_BinarySearch().
   $index = _Array2D_BinarySearch($numerosArray, $str_numero)
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:UsersThe_GeneralDocumentsTIM.au3 - 1 error(s), 0 warning(s)

The fact Au3Check points to the first occurrence is a bug related here:

Function1 is called by main function, with $array as first parameter. Function2 is Array2DBinarySearch. Function1 just gets the index returned by BinarySearch and uses the value changing the subindex: $Array[$index][1]

Edited by TheGeneral
Link to comment
Share on other sites

Yes, I'm a moron sometimes. (Yall hush!) I posted incorrect code. Here is correct code:

Global Const $array[3] = ['a', 'b', 'c']

function1($array)

Func Function1(Const ByRef $parameter)
    Function2($parameter)
EndFunc

Func Function2(Const ByRef $parameter)
    ConsoleWrite($parameter[0] & @CRLF)
    ConsoleWrite($parameter[1] & @CRLF)
    ConsoleWrite($parameter[2] & @CRLF)
EndFunc

Edited by LaCastiglione
Link to comment
Share on other sites

Right ... since const means that the value WILL NOT CHANGE in the function. Are you trying to change something in the array?

THis works for me:

Global $array[3] = ['a', 'b', 'c']

function1($array)

Func Function1(Const ByRef $parameter)
    Function2($parameter)
EndFunc

Func Function2(Const ByRef $parameter)
    ConsoleWrite($array[0] & @CRLF)
    ConsoleWrite($array[1] & @CRLF)
    ConsoleWrite($array[2] & @CRLF)
EndFunc

What's the point of passing a byref array declared in global scope? Why not just use the global directly? Besides the fact that it's a bad habit? Edited by Blue_Drache

Lofting the cyberwinds on teknoleather wings, I am...The Blue Drache

Link to comment
Share on other sites

Yes, I'm a moron sometimes. I posted tincorrect code. Here is correct code:

Global $array[3] = ['a', 'b', 'c']

function1($array)

Func Function1(Const ByRef $parameter)
    Function2($parameter)
EndFunc

Func Function2(Const ByRef $parameter)
    ConsoleWrite($parameter[0] & @CRLF)
    ConsoleWrite($parameter[1] & @CRLF)
    ConsoleWrite($parameter[2] & @CRLF)
EndFunc

Your code is fine. The problem is if you use Function2 after Function1 call: error.

Try that:

Local $array[3] = ['a', 'b', 'c']

Function1($array)
Function2($array)

Func Function1(Const ByRef $parameter)
    Function2($parameter)
EndFunc

Func Function2(Const ByRef $parameter)
    ConsoleWrite($parameter[0] & @CRLF)
    ConsoleWrite($parameter[1] & @CRLF)
    ConsoleWrite($parameter[2] & @CRLF)
EndFunc
Link to comment
Share on other sites

Modified:

Global Const $array[3] = ['a', 'b', 'c']

Function1($array)
Function2($array)

Func Function1(Const ByRef $parameter)
    Function2($parameter)
EndFunc

Func Function2(Const ByRef $parameter)
    ConsoleWrite($parameter[0] & @CRLF)
    ConsoleWrite($parameter[1] & @CRLF)
    ConsoleWrite($parameter[2] & @CRLF)
EndFunc

Link to comment
Share on other sites

If you hit the Continue Anyway button, the program operates ok. It's probably because AU3Check is throwing the error because of the Const declaration. It will even compile and work without a problem as written.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Right ... since const means that the value WILL NOT CHANGE in the function. Are you trying to change something in the array?

What's the point of passing a byref array declared in global scope? Why not just use the global directly? Besides the fact that it's a bad habit?

Because the fact that it's a bad habit. And I guess if you change the name of the global variable then you have to go through your functions and change it there too.

Link to comment
Share on other sites

Right ... since const means that the value WILL NOT CHANGE in the function. Are you trying to change something in the array?

That doesn't apply here because the parameter will only exist inside the function then gets destroyed until the function is called again. So it's only a constant for as long as the function is running then it doesn't exist anymore. It's not being changed in the function, and is prevented from being changed in the function by being a constant. Technically, declaring it as a constant is pointless as long as you write the function to not change the variable inside of it.

What's the point of passing a byref array declared in global scope? Why not just use the global directly? Besides the fact that it's a bad habit?

You would pass an array using ByRef because it saves on memory if using a large array, plus you save time by not copying the contents of that large array into another array first.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

  • 1 year later...

Apparently this problem is still present in the lastest version(1.54.22.0)  ( I just ran into the problem ).

This thread does not seem to contain any solution for the issue, unless I overlooked something (?).

Any way to selectively disable this particular check from when starting from within Scite ?

Link to comment
Share on other sites

It's not correct to pass a constant variable by reference.

I don't see the point at all to use the const keyword in your function parameters.

Either the variable is globaly constant, or you create a constant variable in your function.

Br, FireFox.

Link to comment
Share on other sites

Hi Firefox,

>It's not correct to pass a constant variable by reference.

2 remarks wrt that:

A) Why do you say this is not correct.

If you are familiar with C, i expect const byref to be equivalent of passing a writable pointer to a const entity (see eg http://en.wikipedia.org/wiki/Const-correctness) .

There is nothing fundamentally incorrect with the language construct.

B ) While it is of course always possible that the autoit language does not support this concept,  I do not think that is the case here, because it did not generate get the same error for function 1 which has exactly the same prototype.

You only get this error when you pass through a const byref argument to a another function call, as TheGeneral pointed out in his original code example.

So this seems to indicate an au3check bug, not a language limitation (the code also runs fine, as remarked in a previous post, it is just au3check that complains).

 

>I don't see the point at all to use the const keyword in your function parameters.

There are plenty of reasons to do that, such as: 

- It helps to clarify the user of the function what the function will do with the arguments he provides to it. Eg if the user of a function has large amount of data that he/she does not want to have changed which he needs to pass as an argument,  and the function has a byref, then the only thing the user can do is first make a copy of that data en then passing the copy, because the function is allowed to change the data.  This completely destroys the performance gains of a byref of course. However,  if the function has a const byref type, then the user can safely pass his orignal data to the function knowing that it will not be changed. So in a way, in a lot of cases of byref I think is almost useless to not speficy const byref, the only case where a plain byref is usefull is when the function is meant to fill in the data in the argument you provide.

- prevent bugs in which the function accidentially change  the contents

- perfomance optimisations the compiler can do when he knows the data is constant, ...

(I probably missed a few, google it, there are plenty of in depth discussions regarding this topic).

Edited by Beamer145
Link to comment
Share on other sites

  • Moderators

Beamer145,

If I run this script:

#AutoIt3Wrapper_Run_AU3Check=n

main()

Func main()
   Local $array1[3] =[1, 2, 3], $array2[3] = ["A", "B", "C"]
   Function1($array1)
   Function2($array2)
EndFunc

Func Function1(Const ByRef $parameter)
    Function2($parameter)
EndFunc

Func Function2(Const ByRef $parameter)
    MsgBox(0, "Result", $parameter[0] & @CRLF & $parameter[1] & @CRLF & $parameter[2])
EndFunc

I get what I expect in the MsgBoxes. From this I deduce that AutoIt itself has no problem with what you are doing, it is AU3Check that is throwing the error. And I can see why it would when it sees a function being called twice with very different parameter types. But the code runs perfectly well - just do not run AU3Check when you run or compile it! ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

If you are familiar with C

Well, AutoIt is not C.

 

While it is of course always possible that the autoit language does not support this concept,  I do not think that is the case here

I did not say it's not possible.

 

So this seems to indicate an au3check bug, not a language limitation (the code also runs fine, as remarked in a previous post, it is just au3check that complains).

Indeed.

 

- prevent bugs in which the function accidentially change  the contents

If you don't know what you're doing it's a problem. I use the Const keyword because I know it won't change, not because the script can accidentaly change it (personal preference).

 

- perfomance optimisations the compiler can do when he knows the data is constant, ...

Making a memory pointer constant, shouldn't be very efficient.

Edit: Where the Const keyword is very useful, it's in the includes.

The user is not always aware of these variables names and may edit them in his code.

Br, FireFox.

Edited by FireFox
Link to comment
Share on other sites

- It helps to clarify the user of the function what the function will do with the arguments he provides to it. Eg if the user of a function has large amount of data that he/she does not want to have changed which he needs to pass as an argument,  and the function has a byref, then the only thing the user can do is first make a copy of that data en then passing the copy, because the function is allowed to change the data.  This completely destroys the performance gains of a byref of course. However,  if the function has a const byref type, then the user can safely pass his orignal data to the function knowing that it will not be changed. So in a way, in a lot of cases of byref I think is almost useless to not speficy const byref, the only case where a plain byref is usefull is when the function is meant to fill in the data in the argument you provide.

I was silently in the same boat of confusion as FireFox, until you provided this explanation.  Thank you for that, as I've never thought about it that way before, and actually makes a lot of sense now :)

Link to comment
Share on other sites

I was silently in the same boat of confusion as FireFox

I was not on the same boat, sorry :D

Edit: hm... I should have, then you could share some food with me, remember? :)

@Beamer145

If you said: "Never trust the user input" then okay, but here it's internal.

Edited by FireFox
Link to comment
Share on other sites

The point of using Const is to have as few mutable variables as possible.  The more static the state of the program then the easier it would be to localize bugs.  That has been my experience which is guided by what I've been learning during my stint with functional programming.  FP claims to eliminate a entire classes of bugs that arise from mutable state, impure functions, and eager evaluation.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...