[fpc-devel] Const optimization is a serious bug

Max Vlasov max.vlasov at gmail.com
Sun Jul 10 13:01:56 CEST 2011


On Sun, Jul 10, 2011 at 12:01 PM, Alexander Klenin <klenin at gmail.com> wrote:
> On Sun, Jul 10, 2011 at 18:53, Hans-Peter Diettrich
> <DrDiettrich1 at aol.com> wrote:
>> When the meaning of "const"/"constref" is documented as kind of a *calling
>> convention*, that allows the compiler to optimize the code, no more
>> discussion is required.
>
> "constref" is a calling convention, but "const" is not, since it is
> "optimization hint".
> As you said above, this is the reason why "constref" was invented in
> the first place.
>

Although I liked constref at first, I'd rather think that the current
behavior is more of a side effect of the current implementation. I see
that it was introduce to support well-known c/c++ concept of "give me
a pointer to the thing and I promise I won't change the thing" used in
many apis. But since ansistring is not used in any universal api, the
compiler currently is free to change the meaning and for example pass
not the address of the entry that hold the pointer, but pointer
itself. In other words the compiler if free to choose because
lazarus/fpc is the only place on earth where the pair
constref-ansistring exists (currently). So the constref immunity is
just a side effect

And returning to the original discussion currently I'd like to look
from another point (or maybe just summation of previous thoughts of
others). I think that anything passed by reference (pure reference)
pose the problem OP described, even if you use current "immune"
constref. For example, when you want to investigate every char of the
string you will probably use for i:=1 to Length(Str). As I recall
taking length in advance and using it for every step is even the part
Wirth's pascal as the requirement. If so,  during the loop a callback
or just some call shorten the string, the loop will fail almost for
sure. Not because unexpectedly the string is invalid, but because the
loop expects the string to be longer that it is now. And the problem
like this also can be hard to detect.

So personally I'd not separate the reference-based problems like this
from the problems posed by const. We can blame the compiler for some
optimization results (rarely), but we can not blame the programmer who
cached the length of the string in a local variable thinking that the
string will be same till the end of the function. And imho
understanding that referencing can be dangerous in this regard should
be a part of knowledge for every programmer.

Some good news )... If we look at this, we will see that the problem
exists for every data passed by reference in any language. But in
contrary to some languages  we have a luxury of passing by value not
only register-sized data, but also arge data. And to make things even
better we have a luxury of having a tricky ansistring with its
copy-on-write concept. So for those who appreciate this luxury and
afraid of reference-based problems, using passing ansistrings by value
is the answer. Remember, it's a luxury ;)

Max



More information about the fpc-devel mailing list