Sign in Join
Wiki copytemporary

$rangeChecks: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: $rangeChecks

OldNewLine
1+The [[FPC]]’s [[local compiler directives|local compiler directive]] '''
2+
3+```delphi
4+{$rangeChecks}
5+```
6+
7+''' enables or disable range checks of ordinal data type expressions, the default being
8+
9+```delphi
10+{$rangeChecks off}
11+```
12+
13+. The short form
14+
15+```delphi
16+{$R+}
17+```
18+
19+and
20+
21+```delphi
22+{$R-}
23+```
24+
25+is recognized too.
26+
27+## range checks
28+
29+A range check ensures a value is within the domain of the destination operand. As soon as an operand needs to be “squeezed” into a smaller range, the expression or statement is eligible to a range check.
30+
31+### behavior
32+
33+If a range check fails, the [[runtime error]] 201 “Range check error” is generated. Thus the code sample
34+
35+```delphi>
36+ {$rangeChecks on}
37+ x := y;
38+</syntaxhighlight>
39+is ''semantically'' equivalent to
40+<syntaxhighlight lang=
41+```
42+
43+`   {$rangeChecks off}`\
44+`   x := y;`\
45+`   if (x < low(x)) or (x > high(x)) then`\
46+`   begin`\
47+`       runError(201);`\
48+`   end;`
49+
50+</syntaxhighlight>
51+
52+(The reported memory address at which the error occurred will differ and the compiler may produce optimized code.)
53+
54+### eligibility
55+
56+Range checks can be performed
57+
58+- in [[Becomes|assignments]] (
59+ ``` pascal
60+ :=
61+ ```
62+
63+ ), and more specifically
64+
65+ - when passing actual parameters, or
66+ - indicating [[Array|array]] indices, but also
67+- when doing [[Typecast|typecasts]].
68+
69+For assignments involving constant expressions a range check is performed already at [[compile-time error|compile-time]], but is either a warning or error depending on the current setting.
70+
71+### placement
72+
73+The FPC allows enabling and disabling range checks on a per-statement basis, while Delphi allows changing the setting only a per-routine level.
74+
75+## caveats
76+
77+- It is important to remember that in [[Pascal]] *arithmetic* [[expression|expressions]] are always evaluated on a computer’s “native” (signed) integer data type. If the destination operand of an arithmetic expression is, for instance a
78+ ```delphi
79+ ALUSInt
80+ ```
81+
82+ , this will never trigger a runtime error.
83+- If range checks are meant to be performed when passing parameters, range checks must be enabled *at* the call site.
84+
85+## application
86+
87+Range checks can incur a significant performance penalty. Therefore, the FPC disables range checks by default. However, at least *during* development and prior releases of software, range checks should be enabled to find “obvious” programming mistakes. As a consequence of this practice, if a code fragment is *meant to* exceed the permissible range, it should be documented like this: \<syntaxhighlight lang="delphi\>
88+
89+`   {$push}`\
90+`       {$rangeChecks off}`\
91+`       x := y;`\
92+`   {$pop}`
93+
94+</syntaxhighlight>
95+
96+Use
97+
98+```delphi
99+{$ifOpt}
100+```
101+
102+if code needs to be different on the current range-check-setting: \<syntaxhighlight lang="delphi\>
103+
104+`   {$ifOpt R-} // or R+`\
105+`       …`\
106+`   {$endIf}`
107+
108+</syntaxhighlight>
109+
110+---
111+*From the Free Pascal wiki, page "$rangeChecks", as it stood on 2022-03-05 after a change by Alextp, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
112+Category: FPC

Back to history