How to obtain the memory address of a variable in AutoHotkey v2?

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
return
Posts: 13
Joined: 06 Sep 2018, 22:22
Contact:

How to obtain the memory address of a variable in AutoHotkey v2?

23 Mar 2024, 00:44

hello everyone, In the v2 documentation, I found the StrPtr and Objptr functions, which replace the & function in version 1.1. However, how can I obtain the address of integer and floating-point variables? thanks

Code: Select all

; Define an integer variable
intVar := 123
ptr := &intVar ; Get the address of the integer
MsgBox % Format("The address of the integer is: 0x{:X}", ptr)
just me
Posts: 9466
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: How to obtain the memory address of a variable in AutoHotkey v2?

23 Mar 2024, 04:10

Hello, what do you need it for?
return
Posts: 13
Joined: 06 Sep 2018, 22:22
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

23 Mar 2024, 07:56

just me wrote:
23 Mar 2024, 04:10
Hello, what do you need it for?
Thank you for your response. I used AutoHotkey v1.1 before, and now I am learning AutoHotkey v2.0. I have noticed some differences in this regard. Therefore, I would like to confirm whether AutoHotkey v2.0 does not support obtaining the addresses of variables of integer and float types. From your reply, it seems that directly obtaining the addresses of integer and float variables is not supported now, is that correct?
lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

23 Mar 2024, 22:12

ptr := &intVar never did "Get the address of the integer". It got the address of a string of digits. That is now achieved by StrPtr.

This and most (optimistically "all") other changes are explained in Changes from v1.1 to v2.0. Just search that page for "&var (address-of)".

I would still want to know "what do you need it for?" to provide more pointed advice. For instance, what to do if and when you actually need the address of an integer.
return
Posts: 13
Joined: 06 Sep 2018, 22:22
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

24 Mar 2024, 06:10

lexikos wrote:
23 Mar 2024, 22:12
ptr := &intVar never did "Get the address of the integer". It got the address of a string of digits. That is now achieved by StrPtr.

This and most (optimistically "all") other changes are explained in Changes from v1.1 to v2.0. Just search that page for "&var (address-of)".

I would still want to know "what do you need it for?" to provide more pointed advice. For instance, what to do if and when you actually need the address of an integer.

Thank you very much for your response. Currently, I haven't encountered any application issues; I just have some doubts while learning about v2. Can I understand your response this way? In the previous version (v1), the "address-of" operation returned the address of the internal string buffer of the variable. Does this mean that "&var" is only suitable for string variables?
iseahound
Posts: 1447
Joined: 13 Aug 2016, 21:04
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

24 Mar 2024, 11:44

For the IntPtr question, in the WindowProc commonly x and y are sent together as a series of signed shorts concatenation into an integer. The current method of getting signed shorts from an int is to copy them into a buffer and use NumGet. Having access to IntPtr would allow NumGet to be used on the already existing integer buffer instead of creating a new one.
lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

24 Mar 2024, 16:50

return wrote:Does this mean that "&var" is only suitable for string variables?
var is not a "string variable", but a variable that can contain anything, even if it currently contains a string. &var in v1 can return the address of a string even if the variable contained a number, and sometimes that is what you want; or it can return the address of an object, which is entirely a different thing.

iseahound wrote:The current method of getting signed shorts from an int is to copy them into a buffer and use NumGet.
The "current" method is not to "copy them into a buffer and use NumGet", but to use bitwise-AND/OR and bit-shifting.
iseahound
Posts: 1447
Joined: 13 Aug 2016, 21:04
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

24 Mar 2024, 19:34

As far as I can remember, Microsoft doesn't recommend the use of the LOWORD and HIGH WORD macros because bit magic causes the same problems: signed values can't be retrieved using bitwise operators. For example if I try to get -1, the twos complement of a signed short would be 0xFFFF, and I'd have to copy this value into a Buffer and reinterpret with NumGet regardless. At least purely using bitwise operations, I'm not sure this is possible.
lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

25 Mar 2024, 06:59

@iseahound
I said nothing about LOWORD or "HIGH WORD" (or HIWORD). The correct macros to use for retrieving signed values that have been packed into message parameters are recommended in the documentation for the relevant messages. For instance, GET_X_LPARAM and GET_Y_LPARAM are recommended for use with WM_MOUSEMOVE. These macros are defined as ((int)(short)LOWORD(lp)) and ((int)(short)HIWORD(lp)), which resolve to ((int)(short)((WORD)(((DWORD_PTR)(lp)) & 0xffff))) and ((int)(short)((WORD)((((DWORD_PTR)(lp)) >> 16) & 0xffff))). Clearly, they use bitwise-AND and bit-shifting. :roll:

The effect of the chain of type-casts depends on where the expression is used. int n = GET_X_LPARAM(lParam) would result in sign-extending from 16 to 32 bits, but if n is __int64, it would sign-extend to 64 bits. Sign-extending is generally performed with a single CPU instruction. In C/C++ it would generally be done with typecasts, which we don't have, but we can get the same result with bit-shifting as Descolada showed. It is also demonstrated in the documentation for CallbackCreate. There are other ways to achieve the same result without bitwise operators, with mathematics.

Putting aside Microsoft and the Windows SDK, which have little to no relevance since we're not using C/C++, using bitwise operators is the more common method used in AutoHotkey scripts, since before NumPut existed. It is also more efficient.
User avatar
Seven0528
Posts: 345
Joined: 23 Jan 2023, 04:52
Location: South Korea
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

25 Mar 2024, 07:06

 @iseahound

Code: Select all

var:=-1
msgbox "Arithmetic bit shift right (>>)`t: "    var<<48>>48     ;  -1
msgbox "Logical bit shift right (>>>)`t: "      var<<48>>>48    ;  65535 (0xFFFF)
  • English is not my native language. Please forgive any awkward expressions.
  • 영어는 제 모국어가 아닙니다. 어색한 표현이 있어도 양해해 주세요.
User avatar
Seven0528
Posts: 345
Joined: 23 Jan 2023, 04:52
Location: South Korea
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

25 Mar 2024, 07:35

 Due to my lack of familiarity with bitwise operations, I'm not sure if MAKELPARAM can be implemented solely using bit shifting.
However, I believe GET_X_LPARAM and GET_Y_LPARAM could be adequately implemented using bit shifting.
(I hope others can step in and provide a more detailed explanation of this issue...)

Code: Select all

#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
#define MAKELPARAM(l, h) ((LPARAM)(DWORD)MAKELONG(l, h))

Code: Select all

;  ahk2.0
GET_X_LPARAM(lParam)    {
    return (buf:=buffer(16,0), numput("UShort",lParam&0xFFFF,buf), numGet(buf,"Short"))
}
GET_Y_LPARAM(lParam)    {
    return (buf:=buffer(16,0), numput("UShort",(lParam>>16)&0xFFFF,buf), numGet(buf,"Short"))
}
MAKELPARAM(l, h)    {
    return (buf:=buffer(32,0), numput("Short",l,"Short",h,buf), numGet(buf,"Ptr"))
}

loop    {
    switch (A_Index)
    {
        default:    break
        case 1:     wLow :=  1  ,wHigh :=  2
        case 2:     wLow := -1  ,wHigh :=  2
        case 3:     wLow :=  1  ,wHigh := -2
        case 4:     wLow := -1  ,wHigh := -2
    }
    lpA:=MAKELPARAM(wLow, wHigh)
    x:=GET_X_LPARAM(lpA)
    y:=GET_Y_LPARAM(lpA)
    lpB:=MAKELPARAM(x,y)
    msgbox 
        (LTrim
        A_Index "
        
        " lpA "
        " x "
        " y "
        " lpB
        )
}

Code: Select all

;  ahk2.0
GET_X_LPARAM(lParam)    {
    return (lParam&0xFFFF)<<48>>48
}
GET_Y_LPARAM(lParam)    {
    return ((lParam>>16)&0xFFFF)<<48>>48
}
MAKELPARAM(l, h)    {
    return (buf:=buffer(32,0), numput("Short",l,"Short",h,buf), numGet(buf,"Ptr"))
}

loop    {
    switch (A_Index)
    {
        default:    break
        case 1:     wLow :=  1  ,wHigh :=  2
        case 2:     wLow := -1  ,wHigh :=  2
        case 3:     wLow :=  1  ,wHigh := -2
        case 4:     wLow := -1  ,wHigh := -2
    }
    lpA:=MAKELPARAM(wLow, wHigh)
    x:=GET_X_LPARAM(lpA)
    y:=GET_Y_LPARAM(lpA)
    lpB:=MAKELPARAM(x,y)
    msgbox 
        (LTrim
        A_Index "
        
        " lpA "
        " x "
        " y "
        " lpB
        )
}

  • English is not my native language. Please forgive any awkward expressions.
  • 영어는 제 모국어가 아닙니다. 어색한 표현이 있어도 양해해 주세요.
iseahound
Posts: 1447
Joined: 13 Aug 2016, 21:04
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

25 Mar 2024, 08:42

32-bit autohotkey does exist, so a purely bitwise operation can't be compatible across 32-bit and 64-bit versions.
Descolada
Posts: 1141
Joined: 23 Dec 2021, 02:30

Re: How to obtain the memory address of a variable in AutoHotkey v2?

25 Mar 2024, 08:44

@iseahound 32-bit AHK uses 64-bit integers as well, so the following still works as expected:

Code: Select all

#Requires AutoHotkey v2 32-bit
MsgBox "Running " (A_PtrSize = 4 ? "32-bit" : "64-bit")
MsgBox 0xFFFF << 48 >> 48
iseahound
Posts: 1447
Joined: 13 Aug 2016, 21:04
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

25 Mar 2024, 09:12

Wow so it's safe to assume a 64-bit signed buffer even on 32-bit AutoHotkey? That makes sign extension via bit shifting more reliable.

Someone should figure out the MAKEPARAM macro described above, clearly x | y << 16 doesn't work for negative numbers.
Descolada
Posts: 1141
Joined: 23 Dec 2021, 02:30

Re: How to obtain the memory address of a variable in AutoHotkey v2?

25 Mar 2024, 10:48

@iseahound

Code: Select all

low_word := -1, high_word := -2, dword := MAKELPARAM(low_word, high_word)
MsgBox dword "`n" GET_Y_LPARAM(dword) "`n" GET_X_LPARAM(dword)

; SHORT and INT
GET_Y_LPARAM(lp) => ((lp&0xFFFFFFFF)<<32>>48)
GET_X_LPARAM(lp) => ((lp&0xFFFFFFFF)<<48>>48)
MAKELPARAM(l, h) => (l<<48>>>48)|(h<<48>>>32)

; USHORT and UINT
HIWORD(DWORD) => ((DWORD>>16)&0xFFFF)
LOWORD(DWORD) => (DWORD&0xFFFF)
MAKEWORD(LOWORD, HIWORD) => (HIWORD<<16)|(LOWORD&0xFFFF)
EDIT: fixed SHORT/INT variants
Last edited by Descolada on 26 Mar 2024, 13:43, edited 1 time in total.
lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

25 Mar 2024, 16:55

MAKELPARAM is an alias for MAKELONG, which is defined as ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16)). If you take out the typecasts, you have ((a) & 0xffff) | (((b) & 0xffff) << 16), which does in fact produce the correct result.

Would iseahound care to make any more incorrect statements?
User avatar
Seven0528
Posts: 345
Joined: 23 Jan 2023, 04:52
Location: South Korea
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

25 Mar 2024, 18:19

 The methods utilizing buffers and bitwise shifting return the same value in both 32-bit and 64-bit environments.
Thanks to you, I could make my library better. I want to say thank you to @Descolada and @lexikos for their help.

@iseahound
At first, I also thought that (l & 0xFFFF) | ((h & 0xFFFF) << 16) might not be suitable for representing negative numbers.
I was skeptical about implementing MAKELPARAM using only bitwise shifting, as Int64 and Short have different bit positions for sign determination.
However, surprisingly, there were no significant issues when I tested it.
When casting negative numbers from a wider range data type to a narrower range data type, since the higher bits are already filled with 1s, including the sign bit of the narrower range data type,
the resulting value is still returned as a negative number.

Code: Select all

msgbox format("{:016X}",0)      ;  0000000000000000
msgbox format("{:016X}",16384)  ;  0000000000004000
msgbox format("{:016X}",32767)  ;  0000000000007FFF
msgbox format("{:016X}",-32768) ;  FFFFFFFFFFFF8000
msgbox format("{:016X}",-16384) ;  FFFFFFFFFFFFC000
msgbox format("{:016X}",-1)     ;  FFFFFFFFFFFFFFFF
Thus, there were no logical errors.
Even after testing, there seems to be no difference in the result compared to using buffers.
(Since the definition of Ptr differs between 32-bit and 64-bit systems, we just need to be cautious about that aspect while coding: A_PtrSize==8?lp:lp<<32>>32)

Just a few months ago, I had the exact same curiosity.
Perhaps this post will be helpful: Casting between data types

Code: Select all

;  Utilizing buffers.
GET_X_LPARAM(lParam)    => (buf:=buffer(16,0), numput("UShort",lParam&0xFFFF,buf), numGet(buf,"Short"))
GET_Y_LPARAM(lParam)    => (buf:=buffer(16,0), numput("UShort",(lParam>>16)&0xFFFF,buf), numGet(buf,"Short"))
MAKELPARAM(l, h)        => (buf:=buffer(32,0), numput("Short",l,"Short",h,buf), numGet(buf,"Ptr"))

Code: Select all

;  Utilizing bitwise shifting (recommended).
GET_X_LPARAM(lParam)    => (lParam<<48>>48)
GET_Y_LPARAM(lParam)    => (lParam<<32>>48)
MAKELPARAM(l, h)        => (lp:=(l&0xFFFF)|((h&0xFFFF)<<16), A_PtrSize==8?lp:lp<<32>>32) ;  (lp:=(l<<48>>>48)|(h<<48>>>32), A_PtrSize==8?lp:lp<<32>>32)

Test code is provided below.

Code: Select all

loop    {
    switch (A_Index)
    {
        default:    break
        case 1:     wLow :=  0      ,wHigh :=  0
        case 2:     wLow := -16384  ,wHigh :=  16384
        case 3:     wLow := -1      ,wHigh := -32768
        case 4:     wLow := 16384   ,wHigh := -16384
        case 5:     wLow := -1      ,wHigh := -1
    }
    lpA:=MAKELPARAM(wLow, wHigh)
    x:=GET_X_LPARAM(lpA)
    y:=GET_Y_LPARAM(lpA)
    lpB:=MAKELPARAM(x,y)
    msgbox 
        (LTrim
        A_Index "
        
        " lpA "
        " x "
        " y "
        " lpB
        )
}

Code: Select all

loop 65536    {
    i:=A_Index-1
    wLow:=i
    if (32767<wLow)
        wLow-=65536
    wHigh:=65535-i
    if (32767<wHigh)
        wHigh-=65536
    lpA:=MAKELPARAM(wLow, wHigh)
    x:=GET_X_LPARAM(lpA)
    y:=GET_Y_LPARAM(lpA)
    lpB:=MAKELPARAM(x,y)
    if (wLow!==x || wHigh!==y || lpA!==lpB)    {
        msgbox "False"
        ExitApp
    }
}
msgbox "True"
  • English is not my native language. Please forgive any awkward expressions.
  • 영어는 제 모국어가 아닙니다. 어색한 표현이 있어도 양해해 주세요.
iseahound
Posts: 1447
Joined: 13 Aug 2016, 21:04
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

26 Mar 2024, 09:19

I distinctly remember running into bugs with negative numbers when merging them as two integers side by side into an int64. It's possible the masking is an important step that I didn't use, as clearly shown above. If you think the masking is important, then just say so, otherwise I've clearly given the exact method I normally use. If masking isn't important, then I can show you bugs where this clearly fails.

In any case, you proved yourself that the exact method the C/C++ code uses to sign extend isn't based off the size of an integer buffer (apparently hard coded to 8 bytes in AHK) but rather it calls the sign extend assembly instruction via type casts.

I tend to avoid bit-magic that relies on the size of the underlying buffer, since it often makes no sense from a readability perspective. If you can confirm that using a size of 8 bytes is indeed safe and reccomended, then it wouldn't be out of the question to start encoding special numbers or bit wise transforms that need the number 8. For example, how can one rotate a 8x8 matrix of zeros and ones represented as a 64-bit integer? A meaningless question unless 32-bit ahk really uses 64-bit numbers w/o any underlying gotchas.
User avatar
Seven0528
Posts: 345
Joined: 23 Jan 2023, 04:52
Location: South Korea
Contact:

Re: How to obtain the memory address of a variable in AutoHotkey v2?

26 Mar 2024, 11:43

iseahound wrote:
26 Mar 2024, 09:19
I distinctly remember running into bugs with negative numbers when merging them as two integers side by side into an int64. It's possible the masking is an important step that I didn't use, as clearly shown above. If you think the masking is important, then just say so, otherwise I've clearly given the exact method I normally use. If masking isn't important, then I can show you bugs where this clearly fails.

In any case, you proved yourself that the exact method the C/C++ code uses to sign extend isn't based off the size of an integer buffer (apparently hard coded to 8 bytes in AHK) but rather it calls the sign extend assembly instruction via type casts.

I tend to avoid bit-magic that relies on the size of the underlying buffer, since it often makes no sense from a readability perspective. If you can confirm that using a size of 8 bytes is indeed safe and reccomended, then it wouldn't be out of the question to start encoding special numbers or bit wise transforms that need the number 8. For example, how can one rotate a 8x8 matrix of zeros and ones represented as a 64-bit integer? A meaningless question unless 32-bit ahk really uses 64-bit numbers w/o any underlying gotchas.


 @iseahound
I do not agree with your opinion.
Masking is "obviously" important when combining upper and lower bits through bit shifting. If masking is not applied, most of the upper bits (including the sign bit) will likely be set to 1 when dealing with negative numbers. In such a state, performing bitwise OR to combine two numbers will not change the parts that are already filled with 1s. It cannot be called a bug in the programming language just because incorrect results were obtained due to the individual's lack of understanding.

Code: Select all

#Requires AutoHotkey v2.0
#SingleInstance
GET_X_LPARAM(lParam)    => (lParam<<48>>48)
GET_Y_LPARAM(lParam)    => (lParam<<32>>48)
l:=-32768
h:=98322  ;  Exceeding the range of a short (-32,768 ~ 32,767)
;---------------------------------------------------------------------------------------
                                            ;    64 bit               32 bit
msgbox A_Clipboard := format("{:016X}",l)   ;   FFFFFFFFFFFF8000    FFFFFFFFFFFF8000
msgbox A_Clipboard := format("{:016X}",h)   ;   0000000000018012    0000000000018012
;---------------------------------------------------------------------------------------  1. Using buffers.
lp:=0
buf:=buffer(32,0)
numput("Short",l,"Short",h,buf)
lp:=numGet(buf,"Ptr")
msgbox A_Clipboard := lp                    ;   2148696064          -2146271232
msgbox A_Clipboard := format("{:016X}",lp)  ;   0000000080128000    FFFFFFFF80128000
x:=GET_X_LPARAM(lp)
y:=GET_Y_LPARAM(lp)
msgbox A_Clipboard := x                     ;   -32768              -32768
msgbox A_Clipboard := format("{:016X}",x)   ;   FFFFFFFFFFFF8000    FFFFFFFFFFFF8000
msgbox A_Clipboard := y                     ;   -32750              -32750
msgbox A_Clipboard := format("{:016X}",y)   ;   FFFFFFFFFFFF8012    FFFFFFFFFFFF8012
;---------------------------------------------------------------------------------------  2. Using bitwise shifting without masking (incorrect example).
lp:=(l|(h<<16))
msgbox A_Clipboard := lp                    ;   -32768              -32768
msgbox A_Clipboard := format("{:016X}",lp)  ;   FFFFFFFFFFFF8000    FFFFFFFFFFFF8000
x:=GET_X_LPARAM(lp)
y:=GET_Y_LPARAM(lp)
msgbox A_Clipboard := x                     ;   -32768              -32768
msgbox A_Clipboard := format("{:016X}",x)   ;   FFFFFFFFFFFF8000    FFFFFFFFFFFF8000
msgbox A_Clipboard := y                     ;   -1                  -1
msgbox A_Clipboard := format("{:016X}",y)   ;   FFFFFFFFFFFFFFFF    FFFFFFFFFFFFFFFF
;---------------------------------------------------------------------------------------  3. Bitwise shifting.
lp:=((l&0xFFFF)|((h&0xFFFF)<<16))
msgbox A_Clipboard := lp                    ;   2148696064          2148696064
msgbox A_Clipboard := format("{:016X}",lp)  ;   0000000080128000    0000000080128000
x:=GET_X_LPARAM(lp)
y:=GET_Y_LPARAM(lp)
msgbox A_Clipboard := x                     ;   -32768              -32768
msgbox A_Clipboard := format("{:016X}",x)   ;   FFFFFFFFFFFF8000    FFFFFFFFFFFF8000
msgbox A_Clipboard := y                     ;   -32750              -32750
msgbox A_Clipboard := format("{:016X}",y)   ;   FFFFFFFFFFFF8012    FFFFFFFFFFFF8012
;---------------------------------------------------------------------------------------  4. Bitwise shifting (Ptr).
lp:=((l&0xFFFF)|((h&0xFFFF)<<16))
if (A_PtrSize!==8)
    lp:=lp<<32>>32 ;  Int64 to Int
msgbox A_Clipboard := lp                    ;   2148696064          -2146271232
msgbox A_Clipboard := format("{:016X}",lp)  ;   0000000080128000    FFFFFFFF80128000
x:=GET_X_LPARAM(lp)
y:=GET_Y_LPARAM(lp)
msgbox A_Clipboard := x                     ;   -32768              -32768
msgbox A_Clipboard := format("{:016X}",x)   ;   FFFFFFFFFFFF8000    FFFFFFFFFFFF8000
msgbox A_Clipboard := y                     ;   -32750              -32750
msgbox A_Clipboard := format("{:016X}",y)   ;   FFFFFFFFFFFF8012    FFFFFFFFFFFF8012
Readability can vary depending on the individual. Especially, it tends to be subjective based on the level of understanding. AHK uses Int64 of 8 bytes regardless of whether it is 32-bit or 64-bit. If someone is already familiar with these concepts, bitwise shifting would be sufficiently readable code, while for someone who does not understand it, bitwise shifting might feel like magic.
Pure Numbers: https://www.autohotkey.com/docs/v2/Concepts.htm#pure-numbers
There isn't always only one way to achieve something. This applies not only to programming but also to all problems we encounter in life. I, too, sometimes feel that using buffers leads to better readability and actually writing a lot of code like that. However, in some cases, I prefer writing shorter code using << or >> instead of unnecessarily typing NumPut or NumGet with data types. I don't think one of them is right or wrong. (If you intended to point out the part where I wrote "recommended", I will humbly accept your criticism.)

Code: Select all

#Requires AutoHotkey v2.0
#SingleInstance
lp := 0x00000000FF00FF00
A(lParam)    => (lParam<<48>>48)
B(lParam)    => (buf:=buffer(16,0), numput("UShort",lParam,buf), numGet(buf,"Short"))
msgbox A(lp) "`n" B(lp)
;---------------------------------------------------------------------------------------
sleep 0
startA:=A_TickCount
loop 10000000
    A(lp)
endA:=A_TickCount
sleep 0
startB:=A_TickCount
loop 10000000
    B(lp)
endB:=A_TickCount
;---------------------------------------------------------------------------------------
msgbox endA-startA ;  3453ms
msgbox endB-startB ;  12750ms
Even if I were to accept your claim that using bit shifting leads to poor readability without argument, can't we still view the problem from the perspective of "efficiency"? As long as bit shifting does not drastically reduce readability, this method should also be acknowledged and accepted. While readability is important, efficiency is also crucial, and which one is better code between readable code and efficient code may vary depending on the situation. However, what can be stated clearly is that, at least in this case, neither method is inherently bad.



 You may not know me, but I am someone who has received help from you.
As someone who has used and learned the code written in the numerous libraries you provided,
I feel uneasy about daring to criticize someone smarter than myself.
(especially considering I am not a programmer myself.)
However, I want to say what needs to be said and move on.
I hope you can forgive me. Thank you.
  • English is not my native language. Please forgive any awkward expressions.
  • 영어는 제 모국어가 아닙니다. 어색한 표현이 있어도 양해해 주세요.

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: Dav22, Draken, vmech and 110 guests