AutoHotkey Community

It is currently May 27th, 2012, 6:54 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: September 28th, 2011, 9:19 pm 
Offline

Joined: March 16th, 2011, 6:12 pm
Posts: 172
Location: Worcester, Massachusetts
Code:
;I am calling f() in the same line as a loop parsing the variable string.
;What I want is for f() to change the value of string (by using byref parameters) before the loop starts working.
;i.e. the loop should display letters, because that is the value set in f(), instead of numbers, which is the value set before the parsing loop
;---------------------------------------------------------------------
;In this example, the parsing loop receives the initial value of string as set in the line before the parsing loop:
string = 1.3.5.7 ;7 characters
Loop, Parse, string, % f(string)
   MsgBox, % A_LoopField
;---------------------------------------------------------------------
;HOWEVER, as long as string contains a value of length at least 8 before the line containing the parsing loop, it seems to work
string = 1.3.5.78 ;8 characters
Loop, Parse, string, % f(string)
   MsgBox, % A_LoopField

;---------------------------------------------------------------------
;here's the function
f(ByRef var)
{
   var := "a.b.c.d.e"
   Return "."
}


What is going on? Am I crazy, or stupid? :?

  • Tested on ahk_l and basic
  • Also happens with StringSplit (likewise using the delimiter parameter to call the function.

_________________
★★★ Email me at berban at aim full stop com ★★★


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2011, 1:54 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
At the time the function has been called, the input variable in the preceding arg has already been dereferenced (its contents have been copied into a temporary buffer). I do not consider this a bug. You don't seem to know either, so why did you post in Bug Reports?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2011, 2:35 am 
Offline

Joined: March 16th, 2011, 6:12 pm
Posts: 172
Location: Worcester, Massachusetts
Lexikos:

Well as I demonstrated, it does work sometimes. In the first example I give it does not work, but in the second it does. (By "work" I mean the function successfully modifies the variable before the parsing loop gets a hold of it.) The only thing I change between the 1st and 2nd examples is to add one character to the string's initialized value, making it 8 characters - so I can only assume that this is what determines success or failure. The order of the loops does not matter.

I would understand if this were not possible at all. In that case I would not consider it a bug. It's just the fact that it seems to depend on something so odd as the length of the string before the parsing loop is executed - this is why I put it in the bug reports section. And believe it or not, this behavior is key to a script of mine so I'd at least like to get it sorted out.

_________________
★★★ Email me at berban at aim full stop com ★★★


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2011, 2:42 am 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
I have confirmed berban. Here is same script with some debugging Msgboxes added (and #NoEnv).
Code:
#NoEnv
;I am calling f() in the same line as a loop parsing the variable string.
;What I want is for f() to change the value of string (by using byref parameters) before the loop starts working.
;i.e. the loop should display letters, because that is the value set in f(), instead of numbers, which is the value set before the parsing loop
;---------------------------------------------------------------------
;In this example, the parsing loop receives the initial value of string as set in the line before the parsing loop:
string = 1.3.5.7 ;7 characters

;---------------------------------------------------------------------
;HOWEVER, as long as string contains a value of length at least 8 before the line containing the parsing loop, it seems to work
;~ string = 1.3.5.78 ;8 characters


msgbox before Loop %string%
Loop, Parse, string, % f(string)
{
   if A_Index = 1
      msgbox in loop %string%
   MsgBox, % A_LoopField
}

;---------------------------------------------------------------------
;here's the function
f(ByRef var)
{
   msgbox before change %var%
   var := "a.b.c.d.e"
   msgbox after change %var%
   Return "."
}

_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2011, 2:51 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
Whether or not the input variable is dereferenced before or after the function in the next arg is called is not documented, therefore either behaviour is acceptable.
Quote:
And believe it or not,
I choose not to believe it. Rather than relying on (unreliable) undocumented behaviour, you should move the function call.


Last edited by Lexikos on September 29th, 2011, 2:55 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2011, 2:51 am 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
Found out, it have something todo with the size of the variable. Set capacity to higher value, then it works.
Code:
VarSetCapacity(string, 256)

on top of script.

_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2011, 3:00 am 
Offline
User avatar

Joined: October 7th, 2006, 8:45 am
Posts: 3330
Location: Simi Valley, CA
Code:
VarSetCapacity( data, 1250, 0 )
data := "1.2.3.4"
Loop, Parse, data, ., % g( data )
   data .= "," A_LoopField
msgbox % data

g( byref var ) {
StringReplace, var, var, ., .., a
Return ""
}


Even if this isn't a bug (in documented functionality), it is highly fishy!

_________________
Ternary (a ? b : c) guide     TSV Table Manipulation Library
Post code inside [code][/code] tags!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2011, 3:16 am 
Offline

Joined: March 16th, 2011, 6:12 pm
Posts: 172
Location: Worcester, Massachusetts
Thanks to everyone. :)

_________________
★★★ Email me at berban at aim full stop com ★★★


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2011, 3:44 am 
Offline

Joined: December 26th, 2010, 7:40 pm
Posts: 4172
Location: Awesometown, USA
So we have 2 people measuring the speed at which the apple falls and one saying the apples shouldn't be counted while they fall. I'll play Newton and ask why does this behavior exist?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2011, 4:55 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
Tuncay wrote:
Set capacity to higher value, then it works.
There is at least one exception: ErrorLevel is always dereferenced, by design.
Code:
VarSetCapacity(ErrorLevel, 256) ; Does not affect the result.
ErrorLevel = 1.3.5.7
Loop, Parse, ErrorLevel, % f1(ErrorLevel)
    MsgBox % A_LoopField ; Shows 1, 3, 5, 7
MsgBox % ErrorLevel ; Shows a.b.c.d.e
f1(ByRef var) {
    var := "a.b.c.d.e"
    return "."
}

[VxE] wrote:
Even if this isn't a bug (in documented functionality), it is highly fishy!
Your example definitely demonstrates buggy behaviour on my system: the loop shows "Ÿ;Ÿ;3" and "4". The following example demonstrates similar behaviour:
Code:
VarSetCapacity(var, 256) ; Use dynamic memory.
MsgBox 0,
; &var is stored at this point:
, %var%
; Freeing var invalidates the previous arg. There is also a possibility that
; 'junk' will receive the block of memory which previously belonged to var:
, % VarSetCapacity(junk`, 256 + VarSetCapacity(var`, 0)`, 1) * 0

For performance reasons, an input variable generally isn't dereferenced unless it's also used as an output variable; instead, a pointer to the variable's content is stored in the deref array. Currently this is done before all args are evaluated, which means that a subsequent arg is able to invalidate it. Fixing this will affect the behaviour of berban_'s example; however, the example would still be relying on undocumented behaviour, which is generally unwise.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Google Feedfetcher and 2 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group