W0004: an address whose size prefix is not its variable’s size
An address is where a variable starts (Ed.3 6.5.5.3: the variable “does not need to be of equal or bigger size than the given direct representation, i.e. empty memory or overlapping is permitted”). It takes its own type’s size from that byte, whatever the size prefix says. CODESYS asks that “the data type should match the size prefix”; iecf warns when it does not, and compiles it (docs/dependencies.md).
The sizes: BOOL a bit (X); BYTE, SINT, USINT 1 byte (B); WORD, INT,
UINT 2 (W); DWORD, DINT, UDINT, REAL, TIME, DATE, TOD and DT 4 (D);
LWORD, LINT, ULINT, LREAL, LTIME, LDATE, LTOD and LDT 8 (L).
t AT %MD0 : TIME; (* no warning: 4 bytes, D names 4 *)
r AT %IB12 : REAL; (* W0004: bytes 12 to 15 *)
x AT %QB3 : BOOL; (* W0004: the whole byte 3 *)
An array, structure or STRING lies from its address, its parts back to back; the size prefix is compared with its first element’s or field’s (a BOOL inside takes a byte):
a AT %QW6 : ARRAY[0..9] OF INT; (* no warning *)
b AT %QB6 : ARRAY[0..9] OF INT; (* W0004: an INT is 2 bytes *)
A BOOL at a byte, word or longer takes that whole byte: TRUE is written
as 1, and any value but 0 reads TRUE, as CODESYS documents it. Only a
BOOL starts at a bit: i AT %MX0.3 : INT is E0022.