Identifiers for variables and instances
When naming variables and instances, consider the following points:
- Prefixes of variable and instance names are written in lower case.
- The first character after the prefix is capitalized (enable option First character after prefix should be an upper case letter of naming conventions from Static Analysis, see the following note on Static Analysis).
Static Analysis:
Also note the option to check programming conventions using TE1200 PLC Static Analysis.
Prefixes:
1) Variables of elementary and dynamic data types:
Type | Prefix | Description | Declaration example | Call example | Static Analysis |
---|---|---|---|---|---|
SINT, USINT, | n | Integer, | nErrorID : UDINT; | nErrorID := 16#745; | NC0005-NC0016, NC0035, NC0037, NC0038, NC0160 |
BOOL, BIT | b | boolean (bit) | bConfigured |
| NC0003, NC0004 |
REAL, LREAL | f | float | fPosition |
| NC0017, NC0018 |
STRING | s | string | sNetID |
| NC0019 |
WSTRING | ws | wide string (unicode) | wsRouteName |
| NC0020 |
TIME, LTIME | t | time | tDelay |
| NC0021, NC0022 |
TIME_OF_DAY | td | time of day | tdClockTime |
| NC0025 |
DATE | d | date | dProductionStart |
| NC0023 |
DATE_AND_TIME | dt | date and time | dtProductionStart |
| NC0024 |
ARRAY[...] OF ... | a | array | aMessages |
| NC0030 |
POINTER TO ... | p | pointer | pData | pData := ADR(aBuffer); | NC0026 |
POINTER TO POINTER TO ... | pp | Nested pointer | ppData |
|
|
POINTER TO INTERFACE | pip | Pointer to an interface | pipCylinder |
|
|
REFERENCE TO ... 1) as method input 2) in other cases | 1) according to the basic data type of the reference 2) ref | Reference | 1) nData (with REFERENCE TO INT) 2) refSize | 1) SampleMethod(nData := <…>) 2) refSize REF= nSize; | NC0027 |
- Pointer:
- Typed pointers are preferred over untyped pointers for safety reasons.
- Pointers should be declared as POINTER TO <data type>, where <data type> matches the data type of the variable to which the pointer refers.
- A pointer pointing to an array should be declared as POINTER TO ARRAY [...] OF <data type>, where <data type> matches the data type of the array to which the pointer refers.
- If the data type of the variable to which a pointer points is unknown and therefore cannot be typified, it should be declared as POINTER TO BYTE (or PVOID). The data type DWORD cannot be used as pointer for reasons of 64 bit compatibility.
- The content operator '^' is used for dereferencing a pointer.
- Particular attention should be paid to the validity of the address to which a pointer points.
Sample 1:
nSample : INT;
pSampleToInt : POINTER TO INT;
pSampleToInt := ADR(nSample)
pSampleToInt^ := 123; // Result: nSample = 123
Sample 2:
aSample : ARRAY[1..3] OF LREAL;
pSampleToArrayOfLreal : POINTER TO ARRAY[1..3] OF LREAL;
pSampleToArrayOfLreal := ADR(aSample);
pSampleToArrayOfLreal^[2] := 4.56; // Result: aSample[2] = 4.56
- Pointer arithmetic / pointer comparisons:
- If possible, pointer arithmetic and the use of comparison operators on pointers should be avoided for safety reasons (e.g. increments such as [pSampleToLreal: = pSampleToLreal + SIZEOF(LREAL)] or pointer comparisons using >, >=, <, <=).
- If you cannot do without these operations, use them at most within an array.
- It is particularly important to ensure that the pointers point to elements of the same array, and that the address range of the array is complied with.
2) Instances of objects, and user-defined data types:
Instances of function blocks that are defined in the IEC61131 standard and are of fundamental importance (R_TRIG, TON ...) have no other prefix. Example for correct naming:
fbAdsTimer : TON;
Type | Prefix | Description | Declaration example | Call example | Static Analysis |
---|---|---|---|---|---|
FUNCTION_BLOCK | fb | Instance of a function block | fbWritePersData : FB_WritePersistentData; | fbWritePersData(); | NC0031 |
STRUCT | st | Instance of a structure | stBufferEntry : ST_BufferEntry; | stBufferEntry.nCounter := 5; | NC0032 |
ENUM | e | Instance of an | eMachineState : E_MachineState; | eMachineState := E_MachineState.Stop; | NC0029 |
TYPE (Alias) | according to the internal data type | Instance of an alias type | nNibble : T_Nibble; | nNibble := 16#1; | NC0033 See also: Placeholder {datatype} |
INTERFACE | ip | Instance of an interface | ipCylinder : I_Cylinder; | ipCylinder := fbCylinderBase; | NC0036 |
UNION | u | Instance of a union | uCtrl : U_Control; | uCtrl.aRegister[1] := 16#02; | NC0034 |
3) Other:
Type | Prefix | Description | Declaration example | Static Analysis |
---|---|---|---|---|
Nested types | Only according to the outer type Exception 1: 'pp' for POINTER TO POINTER TO Exception 2: 'pip' for POINTER TO INTERFACE |
| pTelegramData : POINTER TO ARRAY[0..7] OF BYTE; | Disable option Recursive prefixes for combinable data types See also: Naming conventions (2) |
Local and global constants | c |
| VAR CONSTANT VAR_GLOBAL CONSTANT | NC0062, NC0070 |
Global variables |
| The same naming rules apply for global variables. (Do not add a second prefix to the variable names.) | VAR_GLOBAL | Disable option Combine scope prefix with data type prefix See also: Naming conventions (2) |
HRESULT | hr |
| hrErrorCode : HRESULT; | NC0160 |
PVOID | p | pointer | pData : PVOID; | NC0160 |
GUID |
| No prefix is assigned for GUID. |
|
|
AT%I* | optional before the data type prefix: I | allocated input | fActPos AT%I*: LREAL; |
|
AT%Q* | optional before the data type prefix: O | allocated output | fSetPos AT%Q*: LREAL; |
|
Allocated inputs or outputs can have an optional additional prefix 'I' or 'O' before the data type prefix. For instances, it represents the only prefix that is capitalized. The decision for or against the use of this optional prefix should be consistent, so that the name of allocated variables is uniform across the project.