Operator overloading: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Operator overloading
| Old | New | Line | |
|---|---|---|---|
| 1 | + | [[Operator]] overloading refers to re-defining already defined [[Operators|operators]] with new definitions. The term is – although imprecisely – used for operator definitions, that have not yet been defined, too. | |
| 2 | + | ||
| 3 | + | ## Availability | |
| 4 | + | ||
| 5 | + | The [[FPC]] supports [[PXSC]]-style operator overloading, however it is not allowed in [[Mode TP|{$mode TP}]] or [[Mode MacPas|{$mode MacPas}]]. In [[Mode Delphi|{$mode Delphi}]], operator overloading can only be done in the context of classes or advanced records (confer [Delphi documentation](http://docwiki.embarcadero.com/RADStudio/Rio/en/Operator_Overloading_(Delphi))), so the Delphi mode does not support global operator overloads as [[Mode FPC|{$mode FPC}]] and [[Mode ObjFPC|{$mode objFPC}]] do. | |
| 6 | + | ||
| 7 | + | ## Overloadable operators | |
| 8 | + | ||
| 9 | + | Almost all operators can be (re-)defined: | |
| 10 | + | ||
| 11 | + | - assignment operators | |
| 12 | + | - [[Becomes|:=]] | |
| 13 | + | - the special operator `explicit` (referring to explicit [[Typecast|typecasts]]) | |
| 14 | + | - arithmetic operators | |
| 15 | + | - [[Plus|+]] (only binary operation) | |
| 16 | + | - [[Minus|-]] (both unary and binary) | |
| 17 | + | - [[Asterisk|*]] | |
| 18 | + | - `**` | |
| 19 | + | - [[Div|div]] | |
| 20 | + | - [[Mod|mod]] | |
| 21 | + | - [[Slash|/]] | |
| 22 | + | - [[Inc and Dec|inc]] | |
| 23 | + | - [[Inc and Dec|dec]] | |
| 24 | + | - (As of 2020 in the future: `pow`) | |
| 25 | + | - comparison operators | |
| 26 | + | - [[Less than|<]] | |
| 27 | + | - [[Greater than|>]] | |
| 28 | + | - `>=` | |
| 29 | + | - `<=` | |
| 30 | + | - [[Equal|=]] | |
| 31 | + | - [[Not equal|<>]] | |
| 32 | + | - [[symmetric difference|><]] | |
| 33 | + | - [[In|in]] | |
| 34 | + | - logical operators | |
| 35 | + | - [[And|and]] | |
| 36 | + | - [[Or|or]] | |
| 37 | + | - [[Not|not]] | |
| 38 | + | - [[Xor|xor]] | |
| 39 | + | - [[Shl|shl]] | |
| 40 | + | - [[Shr|shr]] | |
| 41 | + | - (As of 2020 in the future: `and_then`, `or_else`) | |
| 42 | + | - and the special operator [[for-in loop|enumerator]]. | |
| 43 | + | ||
| 44 | + | The only operators that can not be overloaded are [[@|@ (address operator)]], [[^|^ (de-referencing operator)]], `as` and [[Is|is]]. | |
| 45 | + | ||
| 46 | + | ## Definition | |
| 47 | + | ||
| 48 | + | An operator is declared as if it was a [[Function|function]], with a few differences: | |
| 49 | + | ||
| 50 | + | - Instead of the word `function` it starts with `operator`. | |
| 51 | + | - The function's [[Identifier|identifier]] is always one of the available operators e. g. `><`, although this would not constitute a valid identifier anywhere else. However, in `{$mode Delphi}` a spelled out operator name *has* to be used. These are allowed in other modes, too (if the specific overload is allowed in a Delphi mode): | |
| 52 | + | ||
| 53 | + | | operator symbol | symbolic name | | |
| 54 | + | |-----------------|------------------------| | |
| 55 | + | | `:=` | `implicit` | | |
| 56 | + | | `+` | `add`, `positive` | | |
| 57 | + | | `-` | `negative`, `subtract` | | |
| 58 | + | | `*` | `multiply` | | |
| 59 | + | | `div` | `intDivide` | | |
| 60 | + | | `mod` | `modulus` | | |
| 61 | + | | `/` | `divide` | | |
| 62 | + | | `=` | `equal` | | |
| 63 | + | | `<>` | `notEqual` | | |
| 64 | + | | `<` | `lessThan` | | |
| 65 | + | | `<=` | `lessThanOrEqual` | | |
| 66 | + | | `>` | `greaterThan` | | |
| 67 | + | | `>=` | `greaterThanOrEqual` | | |
| 68 | + | | `not` | `logicalNot` | | |
| 69 | + | | `and` | `logicalAnd` | | |
| 70 | + | | `or` | `logicalOr` | | |
| 71 | + | | `and` | `bitwiseAnd` | | |
| 72 | + | | `or` | `bitwiseOr` | | |
| 73 | + | | `xor` | `bitwiseXor` | | |
| 74 | + | | `shl` | `leftShift` | | |
| 75 | + | | `shr` | `rightShift` | | |
| 76 | + | ||
| 77 | + | Delphi compatibility operator names | |
| 78 | + | ||
| 79 | + | ||
| 80 | + | Note, `><`, `**` and the bitwise `not` have no equivalent in Delphi, but the symbolic operator designation is allowed instead. | |
| 81 | + | ||
| 82 | + | - The parameter list has to name exactly one or two parameters, depending on the operator. The first formal parameter always refers, if applicable, to the operand on the left-hand side. | |
| 83 | + | - A result identifier has to be specified in front of the colon separating the result type, but can be omitted where the special identifier `result` is available. | |
| 84 | + | - Comparisons *have* to yield a [[Boolean|Boolean value]]. | |
| 85 | + | - The “source” and “target” types of assignment operator overloads must differ. | |
| 86 | + | - Note, the concept of “default parameters,” that means a [[Routine|default value]] for a parameter, only applies to “real” functions. When an operator is used, e. g. in an [[expression]], you can not just skip naming an operand, hoping the compiler will insert “something”. Therefore, the concept of [[Default parameter|default parameter]] values does not apply to operator overloads. | |
| 87 | + | ||
| 88 | + | The following shows a valid operator declaration (in `{$mode Delphi}` the `:=` has to be replaced by `implicit` and the declaration may only appear in the context of class or advanced record definitions). | |
| 89 | + | ||
| 90 | + | ```delphi | |
| 91 | + | operator := (x: myNewType) y: someOtherType; | |
| 92 | + | ``` | |
| 93 | + | ||
| 94 | + | Operators are defined the same way as any other function, by following the signature with a [[Block|block]]. | |
| 95 | + | ||
| 96 | + | Some operator overloads are not allowed: | |
| 97 | + | ||
| 98 | + | - [[User Changes 2.4.0|overloading shortstring assignments with lengths other than 255]] | |
| 99 | + | - [[User Changes 3.2|+ in conjunction with dynamic arrays]] if `{$modeSwitch arrayOperators+}` (since FPC 3.2) | |
| 100 | + | - `+` and `-` in conjunction with enumeration types | |
| 101 | + | ||
| 102 | + | ## Routing | |
| 103 | + | ||
| 104 | + | How an operator overload definition is chosen differs in many aspects how a function is chosen. | |
| 105 | + | ||
| 106 | + | - The assignment operator `:=` is used for *implicit* typecasts. Everywhere, where a value has to be stored in memory, an implicit typecast may occur. Note, that *calling* a [[Routine|routine]] requires storing its parameters in memory, too, thus the parameter list might become subject of implicit typecasts as well, even though on the surface they are not part of an assignment statement. | |
| 107 | + | - Unlike regular function overloads, assignment operator overloads are chosen *by their result type*. | |
| 108 | + | - Operator overloads can not be chosen explicitly by their [[Scope|scope]] they are defined in. Something like `unitDefiningOverloads.+` is not possible. The last operator definition *always* wins and this can not be changed. | |
| 109 | + | - Operator precedence remains as usual for all operator symbols. When defining operators for a new custom type from scratch, the `*` will still bind stronger than the `+`. The operator precedence system can not be altered. FPC does not support [[PXSC]]-style `priority` clauses. | |
| 110 | + | ||
| 111 | + | Operator overloads should be used with caution. They potentially make it harder to identify problems, since it is not necessarily obvious that an operator overload applies. | |
| 112 | + | ||
| 113 | + | ## See also | |
| 114 | + | ||
| 115 | + | - [chapter “Operator overloading” in the “Free Pascal Reference Guide”](https://www.freepascal.org/docs-html/ref/refch15.html) | |
| 116 | + | - [article “operator overloading” in the English Wikipedia](https://en.wikipedia.org/wiki/Operator_overloading) | |
| 117 | + | ||
| 118 | + | --- | |
| 119 | + | *From the Free Pascal wiki, page "Operator overloading", as it stood on 2024-02-28 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).* | |
| 120 | + | Category: FPC | |
| 121 | + | Category: Pascal |
