Что нового

помогите разобрать ошибку called with Const or expression on ByRef-param(s)

WinDos32

Новичок
Сообщения
13
Репутация
0
Код:
Func _replicate( ByRef $KolPovt, ByRef $Stroka)

       if $KolPovt='' or $Stroka='' Then
	     MsgBox(0,'Ошибка',' Один из параметров не заполнен!!')
	     Exit
       EndIf
       if not IsInt($KolPovt) Then
	     MsgBox(0,'Ошибка','Параметр $Count='&$KolPovt&' не является числом')
	     Exit
       EndIf
       $Rez=''
       local $i=0
       While $i<$KolPovt
	         $Rez=$Rez&$Stroka
	         $i+=1
       WEnd
       Return($Rez)
  EndFunc


  Func _RecordLog(ByRef $LogFile, ByRef $SendOrNo, ByRef $LicenseCount, ByRef $DateTime)
;~ 	  prepare string for adding to log file
MsgBox(0,0,$LogFile)
MsgBox(0,'@NumParams',@NumParams)
;~ 	  $StrToLog=$DateTime&$LicenseCount
_replicate(45,'~') ; тут ошибка error: _replicate() called with Const or expression on ByRef-param(s).
	  MsgBox(0,0,$LogFile)
;~ 	   $Open=FileOpen($LogFile,2)
;~        FileWrite($Open,$StrToLog)
;~        FileClose($Open)
   EndFunc



Используйте для AutoIt кода тег [autoit]
autoit.gif

madmasles.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
WinDos32 [?]
Func _replicate( ByRef $KolPovt, ByRef $Stroka)
;...
_replicate(45,'~') ; тут ошибка error: _replicate() called with Const or expression on ByRef-param(s).

В справке всё написано!
The ByRef keyword indicates that the parameter should be treated as a reference to the original.
Ключевое слово ByRef показывает, что параметр следует рассматривать как ссылку на оригинал (переменную).

А у вас, что передаётся в функцию???
 
Автор
W

WinDos32

Новичок
Сообщения
13
Репутация
0
Передаю число повторений и символ что повторить.
А что не так?не пойму
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
WinDos32 [?]
что не так?не пойму
ByRef предполагает изменение этого параметра. А вы вызываете функцию фактически с константами. Правильно так
Код:
Local $var = 45, $str = "~"
_replicate($var, $str)
И в этой вашей функции ByRef совсем не нужен. Просто уберите его и тогда вызов
Код:
_replicate(45,'~')
не будет приводить к ошибке.
 
Автор
W

WinDos32

Новичок
Сообщения
13
Репутация
0
InnI, большое спасибо, вы правы, все получилось!!!
Просто в предыдущих версиях подобный код компилировался.
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
Garrett, а можно поподробнее?
Буду благодарен.
The ByRef keyword indicates that the parameter should be treated as a reference to the original.
Т.е. функция вместо создания новой переменной, использует ссылку на оригинал.
Рекомендуется использовать при большом объеме данных в целевой переменной, например, если используется массив.
ByRef предполагает изменение этого параметра
Этого в справке совсем не увидел.

Правильно ли я понимаю, что если я использую массив на 99999...999 записей, из которых нужно выдернуть несколько значений хитрым алгоритмом, то я должен копировать весь массив в новую переменную?

Или же подразумевается необходимость обязательно указывать Const, если переменная не меняется?
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
mef-t [?]
функция вместо создания новой переменной, использует ссылку на оригинал
Верно.

Этого в справке совсем не увидел.
Это написано "между строк". Если вы передаёте данные по ссылке, то должна быть ВОЗМОЖНОСТЬ их изменения. Const данную возможность исключает.

должен копировать весь массив в новую переменную
Если массив Const, то да. Или можно просто не указывать у параметра функции ByRef, тогда массив будет скопирован автоматически.

обязательно указывать Const, если переменная не меняется
То, что вы сами следите за переменной и не меняете её - это ваши проблемы. Если же вы указали Const, то теперь это проблемы AutoIt. А ему эти проблемы не нужны. Поэтому он проверяет передачу параметров по ссылке - если Const, то ошибка.


Добавлено:
Сообщение автоматически объединено:

mef-t [?]
обязательно указывать Const
Если вы укажите Const ByRef, то вы защитите себя от случайного изменения оригинальных данных внутри функции.
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
Так об этом и речь.
Я указываю ByRef.
Я готов сам следить, изменится или нет. Изменить, если потребуется, или оставить, если потребуется.
Const не указываю.
Перебираю массив, но не заношу в него данные.
От сюда вопрос. Могу ли я указать ByRef без Const.

InnI, большое спасибо за ответы, но просьба при цитировании отвечать не на то, что процитировали, а на оригинал.
InnI сказал(а):
mef-t [?]
Этого в справке совсем не увидел.
Это написано "между строк". Если вы передаёте данные по ссылке, то должна быть ВОЗМОЖНОСТЬ их изменения. Const данную возможность исключает.
Вы пишите, что должна быть возможность, а Garrett писал, что система предполагает изменение этого параметра.
Повторюсь, предполагает не возможность изменения, а само изменение.
Именно по этой причине я и поднял тему.

И похоже система не позволяет мне использовать ByRef, без указания Const, так как я не вношу изменения в массив.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
mef-t,
Пример 1.
Код:
#include <Array.au3>

Global $aArray[5] = [1, 2, 3, 4, 5]

_ArrayDisplay($aArray, '$aArray')
_Change($aArray)
_ArrayDisplay($aArray, '1 After _Change')
_NoChangeOnlyRead($aArray)
_Change($aArray)
_ArrayDisplay($aArray, '2 After _Change')
_NoChangeOnlyRead($aArray)

Func _Change(ByRef $a_Arr)
	For $i = 0 To UBound($a_Arr) - 1
		$a_Arr[$i] *= 10
	Next
EndFunc   ;==>_Change

Func _NoChangeOnlyRead(ByRef Const $a_Arr)
	Local $i_Ind = Random(0, UBound($a_Arr) - 1, 1)
	MsgBox(64, 'Info', '$i_Ind = ' & $i_Ind & @LF & '$a_Arr[$i_Ind] = ' & $a_Arr[$i_Ind])
EndFunc   ;==>_NoChangeOnlyRead
Пример 2.
Код:
#include <Array.au3>

Global Const $aArray[5] = [1, 2, 3, 4, 5]

_ArrayDisplay($aArray, '$aArray')
_NoChangeOnlyRead($aArray)
_NoChangeOnlyRead($aArray)

Func _NoChangeOnlyRead(ByRef Const $a_Arr)
	Local $i_Ind = Random(0, UBound($a_Arr) - 1, 1)
	MsgBox(64, 'Info', '$i_Ind = ' & $i_Ind & @LF & '$a_Arr[$i_Ind] = ' & $a_Arr[$i_Ind])
EndFunc   ;==>_NoChangeOnlyRead
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
mef-t [?]
Могу ли я указать ByRef без Const
Если оригинальный массив не объявлен, как Const, то можно.

Вы пишите, что должна быть возможность, а Garrett писал, что система предполагает изменение этого параметра.
И то и другое писал я. Можно и так: предполагает возможность изменения. Т.е. если понадобится - изменит. Главное, чтобы было разрешение на изменение.

система не позволяет мне использовать ByRef, без указания Const
Позволяет. Вот пример
Код:
Global $array[] = [1,2,3,4,5]
test($array)
Func test(ByRef $a)
  For $i = 0 To 4
    ConsoleWrite($a[$i])
  Next
EndFunc
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
InnI [?]
ByRef предполагает изменение этого параметра.
это неверное утверждение. ByRef ничего не предполагает, это лишь возможность передавать массив в функцию без ее последующего клонирования в теле функции, что происходит если ByRef не использовать.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Kaster [?]
ByRef ничего не предполагает, это лишь возможность передавать массив в функцию без ее последующего клонирования в теле функции, что происходит если ByRef не использовать
Как раз таки предполагает. Если ответственно подходить к написанию кода, то:
ByRef - подразумевает изменения значения переменной по ее указателю.
Const ByRef - исключительно для чтения значения по указателю.

Но в обоих случаях, в первую очередь, служит для исключения клонирования ( при объемных данных хороший выигрыш ), а уже как второстепенное - возврат более одного значения ( ByRef ).
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
InnI [?]
Функция не изменяет параметр. Почему AutoIt выдаёт ошибку?
Так нет ошибок.
Код:
Const $c = 3
Global Const $a = 6

test($c)
test_1($a)
test_2($a)

Func test(Const $var)
  ConsoleWrite($var & @LF)
EndFunc

Func test_1(ByRef Const $var)
  ConsoleWrite($var & @LF)
EndFunc

Func test_2($var)
  ConsoleWrite($var & @LF)
EndFunc
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
madmasles [?]
Я об этом и говорю. Если бы ByRef не предполагал изменение параметра, и в том примере ошибки бы не было. А здесь чётко указано ByRef Const - изменения запрещены, что не является противоречием передаваемой константе. И в данном случае ошибка будет только при попытке изменения константы внутри функции, а в том случае код функции даже не анализируется.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
firex
не нужно путать стиль программирования, ответственный подход и прочее, к причинам возникновения ошибок. в данном случае у автора ошибка вовсе не из-за того, что он передал массив по указателю и не изменил его в теле функции, а в том, что он передает не указатель, а статичный объект. решение - создать переменную, а его уже потом передавать.
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
Я согласен с тем, что ByRef подразумевает ссылку на оригинал.
У меня проблема в том, что если указываю просто ByRef, то получаю ошибку "called with Const or expression on ByRef-param(s)".
Но если пишу Const ByRef, то ошибки нет.

От сюда вопрос, в каком случае обязательно наличие Const.
Передаю массивы. Они константами не объявлялись.
За отсутствие кода просьба не ругать.
Он достаточно большой (не огромный, но большой).
А если пытаюсь вырвать кусок, упростить, то ошибки уже нет.
Вот и спрашиваю, чтобы узнать, куда копать.

------------------
Upd.
Все вопрос снимаю. Нашел.
Передаю массив, как результат функции, а не как переменную.
И тут согласен, редактировать нечего, так как массив не записан в переменную.

Всем спасибо за ответы.
 
Верх