P4040¶
- Code
P4040
- Message
Constant expression result cannot be represented
This error occurs when evaluating a constant expression at compile time produces a result that cannot be represented. Both operands are genuine compile-time constants – the expression is not rejected because it “isn’t constant” (see P4038), but because evaluating it is not possible.
The compiler folds constant arithmetic (+, -, *, /,
MOD, **) at compile time so that later analysis and code
generation see a plain literal rather than an expression tree. This
folding is checked, and the compiler reports P4040 instead of compiling
the program when:
an integer result overflows the arithmetic range used for constant folding, rather than silently producing a wrapped or truncated value that would not match what the target hardware computes at runtime;
a real result is too large to represent and would become infinity (for example
1.0E300 * 1.0E300); ora real result is not a number (NaN) because the operation has no real result (for example a fractional power of a negative base,
(-8.0) ** 0.5).
Reporting the failure at compile time is preferable to letting it surface later as a wrong runtime value with no obvious cause.
Example¶
The following code will generate error P4040:
PROGRAM main
VAR
x : LINT := 100000000000000000000 * 100000000000000000000;
END_VAR
END_PROGRAM
The same applies to real arithmetic whose result exceeds the LREAL
range:
PROGRAM main
VAR
y : LREAL;
END_VAR
y := 1.0E300 * 1.0E300; (* Error *)
END_PROGRAM
To fix this error, use operand values that don’t overflow:
PROGRAM main
VAR
x : LINT := 1000 * 1000;
END_VAR
END_PROGRAM
The same check applies to a constant expression anywhere in a program,
not just a VAR initializer – for example, in an assignment
statement:
PROGRAM main
VAR
y : LINT;
END_VAR
y := 100000000000000000000 * 100000000000000000000; (* Error *)
END_PROGRAM
If the values genuinely need to exceed what a single constant expression can represent, split the computation across multiple typed variables so each intermediate step stays within range, or compute the value at runtime instead of as a compile-time constant.
See Also¶
P4038 – initializer expression does not reduce to a constant value
P4039 – constant expression divides or takes the modulo of a value by zero
Data Types – integer and real type ranges
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.