Your questions are valid but, I'd suggest you think about it a different way.
Instead of thinking of a string as a Pascal string, think of it as just a block of memory (larger than fits in a register) without anything special about it (like being a Pascal string that is a native type in FPC/Delphi.)
Normally, if some type that is a block of memory is passed by value then the compiler makes a copy of it (usually on the stack) and passes the address of that copy to the caller. That way whatever changes are made to it disappear when the caller returns (as it should since the parameter was passed by value.) Note that, with only rare exceptions, any structure that doesn't fit in a register is going to be passed by address even if no changes will be made to the structure by the caller, simply because the structure does not fit in a register.
The critical difference between const and constref is that, const does not imply that the parameter will be passed by reference, it can be passed by value (provided it fits in a register) and enforce that it not be written to by "marking" it const.
Constref on the other hand, explicitly requires the parameter to be passed by reference (even if it would fit in a register and could be passed by value) and, tells the compiler that in spite of being passed by reference, no writing to that parameter is allowed. That is enough for the compiler to pass a reference to the structure _without_ having to make a copy of it on the stack (to ensure the original is unchanged.)
IOW, const MAY end up passing a parameter by reference (depends on the parameter's size) whereas constref will ALWAYS pass the parameter by reference regardless of its size.
I guess you're asking because you plan on supporting strings in SharpBasic. right ?
PS: pretty much what @ASerge and @ccrause stated while I was typing this post.