"In Free Pascal all non-trivial objects are passed by reference". True. But basically it's just a matter of bandwidth. It's cheaper to send a reference, so references are what get sent. And when you stick "var" in front of it, the called function has read / write access. If you leave the "var" out, then it's just read access. (Let's forget about "const" for the time being)
Now - at runtime - if the called function tries to modify a "no var" (read only) reference then the called function creates a local copy and uses the local copy for its local purposes. And this local copy disappears and its resources get freed when the called function exits.
So the take away for me is that objects are routinely passed as references. No need to declare (class& object) in the parameters. "Var" in the parameters means "non const". Not sure what "const" means. It's kinda covered by the absence of "var". So it must have some other meaning to the compiler.
Not quite correct. A normal parameter is read/write just like a var-parameter is, but the caller (not the callee) creates a copy of the value.
Oh boy. I initially agreed with this take. For several hours. Until that other guy mentioned that it was reference counted. Which I'm guessing means that no "deep" copies happen until there is an actual need - until one of the variables becomes different from the shared reference. And I'm assuming that the change that triggers the deep copy (the copy that gets modified) usually occurs "inside" the called function. The caller remains isolated from what's going on in the called function (because of "no var"), and continues to reference the original data. It seems inefficient for the caller to always create a deep copy (and pass a reference to it) when there are often cases in which no deep copy is ever needed.
Only few types are reference counted, namely strings and interfaces. So for the majority the general rules apply that I mentioned before. For reference counted types the compiler increases the reference count before passing such a variable to a normal parameter and then passing in the string/interface variable
as is. For
var-parameters and friends the reference count is not increased before the call.
Sometimes it also depends on the size whether a record is passed as reference or a direct copy (e.g. a copy of a record of size 4 could be passed directly inside a register).
That makes perfect sense. if it fits in a register and it is passed by value, it should be passed in a register (if there any still available, of course.) I presume that in the case of a record of size 4, that implies one (1) field of size 4 and, if there were two fields whose combined size was 4 then two (2) registers would be used, correct ?
If the combined size is indeed 4 it will probably be passed in one register. But in the end it depends on the ABI as well.