I have some observations on the discussion so far. The biggest question
is what the intended behavior is.
Martin wrote:
Well, I have pointed out myself,in my mail, that it probably needs
more documentation. I do not know if it is documented or not.
But it is the answer, I have gotten several times from developers in
the FPC team. So for all I know it is the intended behaviour. At
least intended in FPC (and apparently either intended or at least
implemented in Delphi). So if there is no documentation for it, then
it would appear a problem of documentation, rather than a bug in the
compiler (Again all based on the statements I was given)
Thaddy wrote:
It is a contract between the compiler and the programmer in which it
is expected that the string will not be modified inside a procedure,
function or method.
This is the crux of the controversy. I realized this when I was writing
the original post, but did not mention it explicitly because I thought
it would come up anyway.
The difference between a feature and a bug is the specifications. Here
the specifications are the documentation. I have not found any
documentation in either FPC or Delphi that there is some implicit
contract whereby the programmer promises not to modify other variables
which happen to refer to the same instance as a const parameter. Many
people have repeatedly stated that this is the programmer's fault. If
there is an implicit agreement with the programmer, then yes I agree
with these statements and I believe it is not a compiler bug (although
certainly not good language design).
However I am looking for documentation. Has anyone found anything yet?
If anyone can find anything I would be pleased as it would settle the
question. But lacking any documentation, I don't see how anyone should
know there is an implicit contract. To me, a const parameter means that
you cannot modify that parameter by pointing it to something else, nor
(in the case of strings and dynamic arrays) alter the contents by means
of said parameter. (Although, you can't really alter the contents of
the instance, as copy-on-write simply creates a whole new instance.)
That's what it means in other languages I've used, and nothing more. I
don't see it as implying anything else. Furthermore, as many examples
have shown, the programmer often /cannot/ know whether several variables
refer to the same instance, since the handling of creating and
destroying instances, copy-on-write, etc., is handled by the compiler
and is considered an implementation detail that should be opaque to the
programmer.
I don't know how many of you have actually looked at the demo I posted,
but here is the crucial part. The demo program contains this line:
FCurrentDriverName := Edit1.Text;
In this state, the program works perfectly. However, if this line is
changed as follows:
FCurrentDriverName := Edit1.Text + 'abc';
the program then crashes. IMHO, this is very scary. All you have to do
is make a tiny, harmless change and suddenly a working program crashes.
Also in the demo you will notice that the programmer doesn't even call a
function that takes a const parameter; the problem is caused by setting
a parameter, and it just so happens that behind the scenes the
parameter's setter takes a const parameter.
Unless there is some documentation I am unaware of, I don't agree with
the implicit contract theory. Instances and variables are not the same.
People confuse them because that is actually exactly the point of the
Pascal construct: the compiler creates the illusion that each variable
is an instance. This is why there is copy on write; so you can modify a
variable and it doesn't modify other variables that (prior to
modification) referred to the same instance. But again it is only an
illusion. In the implementation, a variable (or parameter) and an
instance of an automatic type are not the same, and that is where the
problem is rooted. The management of these is an opaque implementation
detail. The programmer cannot be expected to know whether or not the
compiler has chosen to use the same instance for two
variables/parameters, and yet that is what the implicit contract theory
states.
As in C, Java, etc., if I have a const variable, that means it's a const
variable/parameter; i.e., I can't change it to point to something else.
It doesn't carry any implications about other variables that may be
pointing to the same instance. If the implicit const contract is
indeed true, then I agree there is not a compiler bug, just a poorly
conceived language feature (please note I most certainly am not trying
to blame anyone for it though).
The best I have found so far, which is still somewhat ambiguous, is
http://docwiki.embarcadero.com/RADStudio/en/Parameters_%28Delphi%29#Constant_Parameters
which says, A constant (const) parameter is like a local constant or
read-only variable. Constant parameters are similar to value parameters,