Operator: what changed
Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | 1 | An **operator** is a special kind of [[Function|function]]. It can be invoked by placing keywords adjacent to suitable operands. | |
| 2 | 2 | ||
| 3 | 3 | The word *operator* colloquially refers to the symbol or [[Keyword|keyword]] identifying the function that implements the actual operation. `operator` is also a [[Reserved word|reserved word]] that appears in the course of [[Operator overloading|operator overloading]]. | |
| 4 | 4 | ||
| 5 | 5 | ## usage | |
| 6 | 6 | ||
| 7 | 7 | Most [[Operators|operators]] are binary, that means require two operands. Binary operator symbols appear between two operands, like this: | |
| 8 | 8 | ||
| 9 | 9 | ``` pascal | |
| 10 | 10 | x + 5 | |
| 11 | 11 | ``` | |
| 12 | 12 | ||
| 13 | 13 | The plus character identifies the addition operation (Standard Pascal). `x` and `5` are its operands. This style is called infix notation. | |
| 14 | 14 | ||
| 15 | 15 | Unary operators – those which require only one operand – appear in front of their operands (prefix notation), with the exception of `^`, the de-referencing operator, which appears after its operand (postfix notation). Example: | |
| 16 | 16 | ||
| 17 | 17 | ``` pascal | |
| 18 | 18 | -x | |
| 19 | 19 | ``` | |
| 20 | 20 | ||
| 21 | 21 | Here, the minus character identifies the sign inversion operation (Standard Pascal). Blanks between operator and operand do not harm, confer the following section regarding precedence. However, it is common practice to place unary operator symbols back to back with their operands. | |
| 22 | 22 | ||
| 23 | 23 | Operator symbols always appear explicitly, except the implicit typecast and enumerator operator. Unlike in mathematics, no invisible “times” is assumed between two identifiers. | |
| 24 | 24 | ||
| 25 | 25 | Implicit typecasts occur, where a value has to be stored in a memory location. Note, that *calling* a routine triggers implicit typecasts, too. In order to pass the parameters to the routine, they are stored somewhere. Implicit typecasts are not limited to run-of-the-mill assignment statements. | |
| 26 | 26 | ||
| 27 | 27 | ## operator precedence | |
| 28 | 28 | ||
| 29 | 29 | Operands and operators are the building blocks of [[expression|expressions]]. The use of operators is a powerful notational tool, since [[LOC|LOCs]] do not get cluttered by function calls consisting of function identifiers and parentheses, but instead the operands and (ideally) a short symbol achieve the same. Instead of, for example, `sum(x, -8)` the expression `x - 8` evaluates to the same value, while writing five less characters. | |
| 30 | 30 | ||
| 31 | 31 | In order to increase conciseness subexpressions of expressions propagate their intermediate result in a predefined hierarchy. This hierarchy can be superseded by placing parentheses `( )` around subexpressions that shall be treated as *one* expression, so the regular precedence rules apply in the enclosed part remaining uninfluenced from the expression’s rest. Operators that have have higher precedence, bind to operands stronger. | |
| 32 | 32 | ||
| 33 | - | ||
| 34 | - | ||
| 35 | - | ||
| 36 | - | ||
| 37 | - | ||
| 38 | - | ||
| 39 | - | ||
| 40 | - | ||
| 41 | - | ||
| 42 | - | ||
| 43 | - | ||
| 44 | - | ||
| 45 | - | ||
| 46 | - | ||
| 47 | - | ||
| 48 | - | ||
| 49 | - | ||
| 50 | - | ||
| 51 | - | ||
| 52 | - | ||
| 53 | - | ||
| 54 | - | ||
| 55 | - | ||
| 56 | - | ||
| 57 | - | ||
| 58 | - | ||
| 59 | - | ||
| 60 | - | ||
| 61 | - | ||
| 62 | - | ||
| 63 | - | ||
| 64 | - | ||
| 65 | - | ||
| 66 | - | ||
| 67 | - | ||
| 68 | - | ||
| 69 | - | ||
| 70 | - | ||
| 71 | - | ||
| 72 | - | ||
| 73 | - | ||
| 74 | - | ||
| 75 | - | ||
| 76 | - | ||
| 77 | - | ||
| 78 | - | ||
| 79 | - | ||
| 80 | - | ||
| 81 | - | ||
| 82 | - | ||
| 83 | - | ||
| 84 | - | ||
| 85 | - | ||
| 86 | - | ||
| 87 | - | ||
| 88 | - | ||
| 89 | - | ||
| 90 | - | ||
| 91 | - | ||
| 92 | - | ||
| 93 | - | ||
| 94 | - | ||
| 95 | - | ||
| 96 | - | ||
| 97 | - | ||
| 98 | - | ||
| 99 | - | ||
| 100 | - | ||
| 101 | - | ||
| 102 | - | ||
| 103 | - | ||
| 104 | - | ||
| 105 | - | ||
| 106 | - | ||
| 107 | - | ||
| 108 | - | ||
| 109 | - | ||
| 110 | - | ||
| 111 | - | ||
| 112 | - | ||
| 113 | - | ||
| 114 | - | ||
| 115 | - | ||
| 116 | - | ||
| 117 | - | ||
| 118 | - | ||
| 119 | - | ||
| 120 | - | ||
| 121 | - | ||
| 122 | - | ||
| 123 | - | ||
| 124 | - | ||
| 125 | - | ||
| 33 | + | operator precedence | |
| 34 | + | ||
| 35 | + | **precedence** | |
| 36 | + | ||
| 37 | + | **operators** | |
| 38 | + | ||
| 39 | + | **category** | |
| 40 | + | ||
| 41 | + | highest\ | |
| 42 | + | (first) | |
| 43 | + | ||
| 44 | + | - [[Not|not]] (both, logical and bitwise variant) | |
| 45 | + | - unary [[Plus|+]] (sign identity, “positive sign”) | |
| 46 | + | - unary [[Minus|-]] (sign inversion, “negative sign”) | |
| 47 | + | - `**` | |
| 48 | + | - `pow` | |
| 49 | + | - [[@]]<sup>†</sup> | |
| 50 | + | - [[^]]<sup>†</sup> (de-referencing operator) | |
| 51 | + | - `explicit` typecasts | |
| 52 | + | ||
| 53 | + | - unary operators (except\ | |
| 54 | + | destination-dependent operators) | |
| 55 | + | - power | |
| 56 | + | ||
| 57 | + | second | |
| 58 | + | ||
| 59 | + | - [[*]] | |
| 60 | + | - [[And|and]] (both, logical and bitwise variant) | |
| 61 | + | - `and_then` | |
| 62 | + | - [[Slash|/]] | |
| 63 | + | - [[Div|div]] | |
| 64 | + | - [[Mod|mod]] | |
| 65 | + | - [[shl]] (`<<`) | |
| 66 | + | - `shr` (`>>`) | |
| 67 | + | - `as` | |
| 68 | + | - ~~`is` (until FPC 3.3.1, trunk revision 44266)~~ | |
| 69 | + | ||
| 70 | + | - multiplication operators | |
| 71 | + | - conditional typecast | |
| 72 | + | ||
| 73 | + | third | |
| 74 | + | ||
| 75 | + | - [[Plus|+]] | |
| 76 | + | - [[Minus|-]] | |
| 77 | + | - [[Or|or]] (both, logical and bitwise variant) | |
| 78 | + | - `or_else` | |
| 79 | + | - [[Xor|xor]] (both, logical and bitwise variant) | |
| 80 | + | ||
| 81 | + | - addition operators | |
| 82 | + | - complex logical operators | |
| 83 | + | ||
| 84 | + | fourth | |
| 85 | + | ||
| 86 | + | - [[Less than|<]] | |
| 87 | + | - [[Greater than|>]] | |
| 88 | + | - [[Equal|=]] | |
| 89 | + | - [[Not equal|<>]] | |
| 90 | + | - `<=` (both, ⊆ as well as ≤) | |
| 91 | + | - `>=` | |
| 92 | + | - `in` | |
| 93 | + | - [[symmetric difference|><]] | |
| 94 | + | - [[Is|is]] (since FPC 3.3.1, cf. [Issue \#35909](https://bugs.freepascal.org/view.php?id=35909)) | |
| 95 | + | ||
| 96 | + | - relational operators | |
| 97 | + | - inheritance test | |
| 98 | + | ||
| 99 | + | lowest\ | |
| 100 | + | (last) | |
| 101 | + | ||
| 102 | + | - [[Becomes|:=]] (implicit [[Typecast|typecasts]]) | |
| 103 | + | - `enumerator` (if applicable) | |
| 104 | + | ||
| 105 | + | - destination-dependent conversions | |
| 126 | 106 | ||
| 127 | 107 | <sup>†</sup>) This symbol does not refer to an actual operator, but is (imprecisely) called as one. | |
| 128 | 108 | ||
| 129 | 109 | [[Inc and Dec|Inc and dec]] are pseudo operators: They may be redefined via the operator overloading mechanism, but they can not appear in expressions, like any function could. Therefore their precedence is moot. | |
| 130 | 110 | ||
| 131 | 111 | `Include` and `exclude` are also not operators, but shorthand for common LOCs. | |
| 132 | 112 | ||
| 133 | 113 | `@` and `^` albeit being called operators, are *not* operators, but rather instruct the [[Compiler|compiler]] to interpret an [[Identifier|identifier]] differently than usual. This is not done via any function, but compiler intrinsics. | |
| 134 | 114 | ||
| 135 | 115 | > **Note:** Operator precedence is slightly modified by `{$modeSwitch ISOUnaryMinus}`, which is enabled by default in [[Mode iso|{$mode ISO}]] and [[Mode extendedpascal|{$mode extendedPascal}]]. There, the unary minus is on the same level as other addition operators are. | |
| 136 | 116 | ||
| 137 | 117 | ### evaluation order | |
| 138 | 118 | ||
| 139 | 119 | > **Note:** Operator precedence does not infer evaluation order. The compiler may re-arrange expressions according to associative and commutative properties of operators. | |
| 140 | 120 | ||
| 141 | 121 | No assumptions shall be made, and there is no guarantee, that expressions are evaluated from left to right (or the reverse direction). The [[FPC]] for instance, evaluates more “complex” subexpressions first before moving on to “trivial” parts (ratio: avoiding register spilling). | |
| 142 | 122 | ||
| 143 | 123 | If a subexpression *has* to be evaluated first, e.g. a function triggering some side-effects, the expression has to be split up into two separate statements. For example: | |
| 144 | 124 | ||
| 145 | 125 | ``` pascal | |
| 146 | 126 | x := foo() + bar(); | |
| 147 | 127 | ``` | |
| 148 | 128 | ||
| 149 | 129 | The compiler may evaluate `foo()` or `bar()` first. If `bar()` ought to be evaluated first at all events, the statement has to be split into two separate ones: | |
| 150 | 130 | ||
| 151 | 131 | ``` pascal | |
| 152 | 132 | x := bar(); | |
| 153 | 133 | x := x + foo(); | |
| 154 | 134 | ``` | |
| 155 | 135 | ||
| 156 | 136 | > **Note:** The [[Compiler directive|compiler directive]] [[$boolEval|{$boolEval off}]] enables “lazy” evaluation. Parts of expressions may not be evaluated at all. | |
| 157 | 137 | ||
| 158 | 138 | ## see also | |
| 159 | 139 | ||
| 160 | 140 | - [“Operators”](https://www.freepascal.org/docs-html/ref/refse88.html) in the FreePascal Reference Guide | |
| 161 | 141 | - Tutorial: [[Basic Pascal Tutorial/Chapter 1/Assignment and Operations|assignment and operations]] | |
| 162 | 142 | - [[management operators]] – a collection of specially supported routines | |
| 163 | 143 | ||
| 164 | 144 | --- | |
| 165 | 145 | *From the Free Pascal wiki, page "Operator", as it stood on 2022-08-06 after a change by Kai Burghardt, 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).* | |
| 166 | 146 | Category: Code |
