P4026¶
- Code
P4026
- Message
Function call argument type does not match parameter type
This error occurs when a function call passes an argument whose type does not match the
declared parameter type. IronPLC converts the argument implicitly where the conversion is
lossless — between integer types, from a narrow integer to a real, from REAL to
LREAL, and within the bit-string types — and reports this error for every other
mismatch, such as a narrowing conversion, a real argument for an integer parameter, or a
signed argument for an unsigned parameter.
For the full set of allowed implicit conversions, see Type Conversions.
A whole array, a structure, an enumeration or a function block instance is only ever
its own type, and no conversion applies to it. Passing one for a parameter of any other
type, including a generic category such as ANY_NUM or ANY_STRING, is this error.
An array or structure is accepted for a parameter whose type has the same shape, such
as an inline ARRAY[1..2] OF DINT for a parameter declared with a named array type of
two DINT elements.
The arithmetic functions ADD, SUB, MUL and DIV are the exception: they
accept the numeric types and the time and date types, so a mismatch in their inputs is
reported as P4049 instead, as it is for the operators +, -, * and /.
Example¶
The following code will generate error P4026:
FUNCTION DOUBLE_REAL : REAL
VAR_INPUT
A : REAL;
END_VAR
DOUBLE_REAL := A + A;
END_FUNCTION
PROGRAM main
VAR
result : REAL;
x : DINT;
END_VAR
result := DOUBLE_REAL(x); (* Error: DINT argument for REAL parameter *)
END_PROGRAM
The variable x is DINT, but parameter A expects REAL. A 32-bit integer
does not fit exactly in REAL’s 23-bit mantissa, so the conversion is not implicit.
An INT argument in the same position is accepted, because every 16-bit integer is
exactly representable in REAL.
To fix this error, use an explicit type conversion:
result := DOUBLE_REAL(DINT_TO_REAL(x));
Widening to LREAL is the other way out: every integer type converts implicitly to
LREAL, so a parameter declared LREAL accepts x as written.
Passing a whole array where a single value is expected is the same error:
PROGRAM main
VAR
names : ARRAY[1..2] OF STRING[8];
n : DINT;
END_VAR
n := LEN(names); (* Error: ARRAY[1..2] OF STRING[8] for an ANY_STRING parameter *)
END_PROGRAM
To fix this error, pass one element of the array:
n := LEN(names[1]);
Think IronPLC is wrong about this?
If you believe this diagnostic is incorrect, open an issue on GitHub with a small sample that demonstrates the problem.