Structuring code

Well, you know about the auto-execute section now. You learned how to trigger code by hotkeys and hotstrings. But you needn’t put all your code in the auto-execute section or in hotkeys etc. There are some other ways to structure your code. One of those are user-defined functions, which we will cover later. The other one are so-called labels.

A basic label:

A label consists of the label name, the code to execute and (usually) a return statement. An example:

1 MyLabel: ; the label name followed by a colon
2 MsgBox A label! ; the code to execute
3 return ; stops the label

Execution flow on labels

Unlike hotkeys, labels do not stop execution automatically as if there was a return before it. This allows the execution flow to “fall through” several labels. Also, if you just copy the above code, save it as script and execute it, the MsgBox will be shown automatically, as there’s no return before the label. This differs from function behaviour.

Jumping to a label

Except for some special labels AutoHotkey uses directly, you need a possibility to jump from your current line to a label to use it. There are 2 commands for this: gosub and goto. The big difference:

An example for illustration:

 1 MsgBox This is the auto-execute section.
 2 Gosub MyLabel ; jumps to MyLabel and back
 3 MsgBox Auto-execute section again!
 4 GoTo MyLabel ; jumps to MyLabel and stays there
 5 MsgBox ; this will never be executed as goto doesn't return
 6 return
 8 MyLabel:
 9 MsgBox This is a label.
10 return ; goto will exit the script here

Using labels

Besides the possibilities above, there are some ways to use labels with built-in functionality.


OnExit let’s you specify a label name to which the script will jump to before it exits. You can put there some routines to clean up some memory, files or whatever your script used.

Gui labels

When we deal with GUIs later, we will specify label names (so-called “g-Labels”) that are launched if something happens to a control. Also, there are some standard label names that are launched when a GUI closes etc.


If you add a label named OnClipboardChange to your script, it will be launched whenever the system clipboard changes. You can retrieve the contents and modify or react on them.


One more thing to mention is the built-in function IsLabel() which can be used to test if a given name (often a variable) is an existing label. If you try to jump to a non-existing label, AutoHotkey will throw an error. In case you have a dynamic label name, you can use this function to avoid this error.

spaghetti code

Generally, labels and any other feature exist to be used. However, be careful: excessive use of labels combined with Gosub and especially GoTo can lead to so-called “spaghetti code”: code that nobody can understand, that you loose control of, and that is very very difficult to debug or improve, potentially leading to infinite loops. An example:

 1 ; any AutoHotkey version
 2 ; NOTE: to be replaced with a real-world example
 4 #Q::
 5 GoTo label1
 6 return
 8 label1:
 9 MsgBox
10 a := 1
11 goTo label3
12 return
14 label2:
15 a := 0
16 goTo label3
17 return
19 label3:
20 if (a)
21 	goto label2
22 return

Now try to find out what the code does in what order. How long do you need?