Peter N Lewis wrote:
I think a compiler directive is too broad here because you usually don't want it for all types (in particular simple types).
Why would you have "const" on a simple type which would be passed by value to get the same result...?
To state that it's read-only. (Yes, `protected' does the same, but those preferring BP style, or trying to write BP compatible code, use `const' ...)
As far as I can see, the only purpose in the "const" keyword in this case is to get it passed by reference, but not allowed to be modified so you can pass things like strings and records without the cost of copying or the fear of changing your source. For simple types you would just pass by value.
Perhaps you really weren't aware of it (I'm almost getting the impression when I read this), but both `const' and `protected' forbid modification of the parameter within the routine, even if it's passed by value. This can be a tool to avoid some bugs (especially for value parameters -- one might accidentally assign to the parameter, thinking it was a reference parameter; a plain value parameter would accept the assignment and discard the value when leaving the routine; a `protected' or `const' parameter will signal an error).
But even then, I'm happy for the compiler to say: "const" with simple values does nothing, "const" with not-simple values is undefined unless the compiler directive XYZ is set, in which case it always passes by reference.
That's basically what GPC does without the directive ATM already. The question is what simple values are.
As I said, an array of 255 chars is most likely not simple; the critical values are quite different ones. But if you want to declare it explicitly (and be 100% sure that it will always be passed by reference), the best so far to me still seems a new syntax.
As you all know, I don't like adding new keywords either. Reusing existing keywords is a bit better ... `const var Foo: Bar' ...?
That's fine by me, except if that would allow passing constant strings and such, then how is it different to "protected var" allowing passing constant strings? The latter seems the easiest solution (not to mention keeping the current status and not requiring me to go and change all the interfaces again ;).
It violates EP, quite simply. (So we'd need a dialect version check and all the blah blah, and then I'll rather have a different syntax to make the difference explicit.)
I think that `const var' looks a bit strange. But given that `const' in parameter lists means `read-only, accept values' and `var' here means `pass by reference', it may be understandable ...
Waldek Hebisch wrote:
Peter N Lewis wrote:
As far as I can see, the only purpose in the "const" keyword in this case is to get it passed by reference, but not allowed to be modified so you can pass things like strings and records without the cost of copying or the fear of changing your source. For simple types you would just pass by value.
I have not checked the rules gpc uses. But speaking about purpose, consider:
type alpha : array[1..8] of char;
On 64-bit machine passing `alpha' by value (in a register) is likely to more efficient then passing reference. On 32-bit machine reference is probably more efficient. On machines with vector registers it may pay off to pass larger arrays in registers. So one meaning is "the value will not change, use most efficient method to pass parameters".
Exactly, that's how we defined it. (Well, we don't strictly find the most efficient method currently, just some heuristics, but that's the idea.)
Also, `var' (even protected) parameter has special semantics: the value _can_ change due to direct assignments to global variables (or due to routine calls). In many cases the compiler has to read values directly from memory, even if previously read value is still available in registers. Indirect modifications of `const' may be considered as an error, since the programmer can not rely on parameters being modified (or not modified). So, in principle `const' parameters allow better optimization.
Yes. I don't know if the backend supports it (yet), but in principle we could avoid aliasing problems.
Of course, once we document that certain `const' parameters are always passed by reference programmers may try dirty tricks...
That's why we don't. :-) In particular, since it may vary between platforms, providing for very nice kinds of bugs ...
Concerning `Str255': it would take rather strange machine (high bandwidth, high latency distributed machine ???) for such type to be passed by value. For such machine sticking to Apple ABI seem pointless...
Perhaps, one day, 2048 bit registers ... ;-)
Peter N Lewis wrote:
Despite the claims in GPC to the contrary, "const" array parameters must be passed by reference according to the ABI anyway, and there is no way for the compiler to optimize it out since in these cases it can never have any access to the code behind the declaration since it is in the system.
BTW, are there array values in MP at all, or are the only arrays where it really matters in fact strings?
Frank