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); or

  • a 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.