Note also the TwinCAT 3 programming conventions (section "TwinCAT 3 programming conventions")

Rules for identifier allocation

Rules for the identifier of a variable

An identifier must contain the following letters and numbers:
An identifier may not contain spaces or special characters (!, &, ß,...).
TwinCAT is not case-sensitive, that is to say: VAR1 and var1 denote the same variable.
TwinCAT recognizes the underscore, i.e. A_BCD and AB_CD, for example, are treated as two different identifiers. Usually no separators, such as the underscore, are used between the words.
Double underscores ('__') should be avoided, because they are used for internal variables.
There is no limit to the length of an identifier.

Rules for the multiple use of identifiers (namespaces)

A local identifier may only be used once.
An identifier must not be identical to a keyword (for example variable type).
A global identifier may be used repeatedly. If a local variable has the same name as a global variable, the local variable has priority within a POU.
A variable that is defined in a global variable list can have the same name as a variable that is defined in another GVL. TwinCAT offers the following standard-extending functionalities with regard to the namespace/scope of variables:
Operator - Global namespace: An instance path that starts with a dot always opens a global namespace. If there is a local variable, for example nVar, which has the same name as a global variable, .nVar is used to address the global variable.
The name of a global variable list can unambiguously define the namespace for the included variables. In this way, you can declare variables with the same name in different global variable lists and still address them uniquely by prefixing the list name.
Example: GVL1.nvar := GVL2.nVar; (*nVar from GVL2 is copied to nVar in GVL1*)
Variables that are defined in the global variable list of a library that is integrated in the project can be addressed unambiguously according to the following syntax: <namespace library>.<name of the GVL>.<variable name>.
Example: GVL1.nVar := Lib1.GVL1.nVar (* nVar from GVL1 in library Lib1 is copied of nVar in GVL1*)
For a library, a namespace is defined when it is inserted via the library manager. In this way, you can unambiguously address a library function block or a library variable via <namespace library>.<function block name|variable name>. For nested libraries, note that the namespaces of all participating libraries have to be specified in sequence.
Example: If Lib1 is referenced by Lib0, the function F_Sample contained in Lib1 is addressed via Lib0.Lib1.F_Sample: nVar := Lib0.Lib1.F_Sample(nValue:=4); (*Return value of F_Sample is copied to variable nVar in the project*)

See also:

Variable types and special variables
Data types