Re: [fpc-devel] Const optimization is a serious bug

2011-07-11 Thread Jonas Maebe

On 11 Jul 2011, at 02:08, Chad Berchek wrote:

 Even if the calling convention does not change, the semantics can, as 
 currently implemented. Even within a single platform const is ill-defined. 
 Consider the case of AnsiString. There are three cases as it is currently 
 implemented:
 
 1) Ref count  1 when passed as const parameter results in strict 
 pass-by-value semantics
 2) Ref count = 1 and you modify the original instance in-place results in the 
 value of the parameter changing
 3) Ref count = 1 and you modify the original reference such that the 
 instance's ref count decreases to zero and it may crash or just give weird 
 behavior

Case 1) is the same as 2) and 3). Even if the reference count is initially 100, 
the called routine can overwrite all but one of them first and then either do 
2) or 3).


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-11 Thread Alexander Klenin
On Mon, Jul 11, 2011 at 15:35, Hans-Peter Diettrich
drdiettri...@aol.com wrote:
 Alexander Klenin schrieb:
 To which data type do you want apply your constval modifier, with which
 concrete effects?

 To any datatype, of course. The result should be:
 1) Parameter is passed by value

 How to pass objects by value?
That, as I said above, is a separate good question.
Until it is resolved, I agree with your suggestion of giving warning
(or even error) on const and constval object parameters.

 Records with embedded AnsiStrings or other managed types?
That is already done in the usual by-value mechanism.

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Hans-Peter Diettrich

Alexander Klenin schrieb:


Martin, I do not know why you and Hans suddently have an urge to insult Chad,
but he really did not deserve this.


Perhaps a threshold was reached, when the same wrong argumentation was 
refrained too often.




As for the whole optimization hint angle, I'd like to note that:
1) This is contrary to previous posts in this same thread, where
  FPC developers insisted that const semantics is defined as
  no refcounting, which is quite different from a hint.


Refcounting is one optimization aspect, passing large data byref another 
one.



2) If const is indeed an optimization hint, that places it in the
same category as,
  say, inline. What would you say if adding inline keyword to a procedure
  converted working program into randomly crashing one? I'd say this
is optimization bug,
  much like the title of this thread.


IMO the situation is very different for inline. Both optimizations 
have very little in common (from the compiler VP).



3) Current documentation (http://www.freepascal.org/docs-html/ref/refsu58.html)
  declares that const modifier is retaining the semantics of
passing by value,
  so there is definitely a bug here -- you can declare it to be bug in
specification, but still.


Sorry, I cannot find anything like this statement in the link. The 
addressed byval/byref move doesn't change the semantics, provided that 
the item is not modified in user code - this can be verified for records 
or other simple types by the compiler.


The situation is very different for parameters, which already *are* 
references. In these cases the passed object can be modified, regardless 
of const, the compiler only checks that the reference *itself* is not 
changed.


The situation is different again for *managed* types, which also are 
always passed byref. Here the removal of refcounting applies.




On the more constructive note, I have yet another proposal:
1) Leave current const implementation broken as-is.
2) Introduce new constval modifier which is similar to const,
  but guarantees correct by-value semantics.


If you want to introduce different keywords, then please different for 
beforementioned cases. E.g.

constval x: integer; //all value-types
constref r: Trecord; //also ShortString
const??? o: TObject; //all references, except following
const??? s: AnsiString; //all managed types

BTW the constref keyword has been introduced for *external* 
subroutines (MacOS ABI), which require that a value is always passed by 
reference, independent from SizeOf(param) and SizeOf(pointer). Its use 
should be restricted accordingly.




3) Slowly migrate existing code to either constref or constval,
  use const for legacy/compatibility/extreme optimization cases.


IMO const is already used far too often in the FPC/Lazarus 
libraries. The compiler instead should treat it as an error, when an 
unmanaged (object) reference is used with const.


It's kidding when somebody requires that the compiler prevents him from 
inadvertently modifying an given value parameter. He who doesn't have 
enough coding discipline to care for such restrictions himself, will 
make more logical errors that no compiler can detect.


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.


/IMO

DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Max Vlasov
On Sun, Jul 10, 2011 at 12:01 PM, Alexander Klenin kle...@gmail.com wrote:
 On Sun, Jul 10, 2011 at 18:53, Hans-Peter Diettrich
 drdiettri...@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
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Martin

On 10/07/2011 05:34, Alexander Klenin wrote:


As for the whole optimization hint angle, I'd like to note that:
1) This is contrary to previous posts in this same thread, where
   FPC developers insisted that const semantics is defined as
   no refcounting, which is quite different from a hint.

Jonas himself pointed out that this documentation is at least misleading.

Anyway: I have at no point said or implied (or at lest have I not mean 
to do so) that the documentation was perfect. In fact, I do thing the 
documentation has severe shortcomings.


Anyway, so far I have talked about the feature. The feature is correctly 
implemented (if the defintition is known).



2) If const is indeed an optimization hint, that places it in the
same category as,
   say, inline. What would you say if adding inline keyword to a procedure
   converted working program into randomly crashing one? I'd say this
is optimization bug,
   much like the title of this thread.
I guess an inline can make a program crash. I the inlined procedure 
contains code trying to access it's own stack frame, and being inlined 
actually access the stackframe of the would-be-caller...
I am not going to try to prove this, but I guess with enough 
determination it can be done.


Anyway, as we well know by now const is more than that, hence it can 
not be compared with inline.


...and never mind any issues with the documentation of it. If the docs 
are wrong, then correct them, but do not blame the feature as bad, 
because the docs are bad...



3) Current documentation (http://www.freepascal.org/docs-html/ref/refsu58.html)
   declares that const modifier is retaining the semantics of
passing by value,
   so there is definitely a bug here -- you can declare it to be bug in
specification, but still.


No argument with that. As I pointed out, the correctness (or 
incorrectness)  were never my point



On the more constructive note, I have yet another proposal:
1) Leave current const implementation broken as-is.

sarcasm
You made a typo:
1) Leave current const implementation WORKING as-is.
;-p  SCNR
/sarcasm


2) Introduce new constval modifier which is similar to const,
   but guarantees correct by-value semantics.

no problem with that.


3) Slowly migrate existing code to either constref or constval,
   use const for legacy/compatibility/extreme optimization cases.

Maybe...

BUT: I have actually used const in some places with exactly the intend 
to have it doing what it does.
I have used const with the very intention of the ref-count not being 
increased, and by this with the effect of the implicit exception frame 
not being needed.


Given that, I would not migrate that code to anything else.

BTW: when I first did that, I made the very mistake of doing it wrong 
myself too. I learned, I corrected my code, I started using it as it is 
meant to..


Best Regards
Martin


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Martin

On 10/07/2011 11:33, Marco van de Voort wrote:


To be honest, I'm a bit surprised by the progression of this discussion. I
sympathise a bit with the proponents of a simple disable this optimization
switch, but to me the rest all sounds like people desperately defending
their turf, and losing sight of the big picture.
I agree the discussion, if the feature should be as it is, went off, far 
out off control. And I myself take a considerable share of the blame in 
making it do so.


The discussion was meant to be about, what can or should be done, in 
addition to the feature. Accepting the feature itself as it is.

I think the finegrained detection option that Martin proposes has a bad


work vs occuarance tradeoff, but a global killswitch for this might be
enough.
I do agree. At least from the point of the developer(s) that have to 
implement it. And I do accept that.


Never the mind, that does not mean that not from the users point of 
view, it would be nice to have. not that it cannot be proposed.


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Hans-Peter Diettrich

Alexander Klenin schrieb:


3) Current documentation
(http://www.freepascal.org/docs-html/ref/refsu58.html)
 declares that const modifier is retaining the semantics of
passing by value,
so there is definitely a bug here -- you can declare it to be bug in
specification, but still.

Sorry, I cannot find anything like this statement in the link.

It is a direct quote -- you can use find on page feature of your browser
(usually activated by pressing Ctrl+F) to locate it.


The whole sentence applies to the byval/byref modification, nothing is 
said about the cases where references are passed even without const. In 
this case I agree that aliasing can change the semantics.




On the more constructive note, I have yet another proposal:
1) Leave current const implementation broken as-is.
2) Introduce new constval modifier which is similar to const,
 but guarantees correct by-value semantics.

If you want to introduce different keywords, then please different for
beforementioned cases. E.g.
constval x: integer; //all value-types
constref r: Trecord; //also ShortString
const??? o: TObject; //all references, except following
const??? s: AnsiString; //all managed types


I am not quite sure what are you asking here. Can you elaborate?


To which data type do you want apply your constval modifier, with 
which concrete effects?




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.


From the user VP both affect code generation only. Both can be broken 
by by aliasing.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Alexander Klenin
On Mon, Jul 11, 2011 at 04:09, Hans-Peter Diettrich
drdiettri...@aol.com wrote:
 If you want to introduce different keywords, then please different for
 beforementioned cases. E.g.
 constval x: integer; //all value-types
 constref r: Trecord; //also ShortString
 const??? o: TObject; //all references, except following
 const??? s: AnsiString; //all managed types

 I am not quite sure what are you asking here. Can you elaborate?

 To which data type do you want apply your constval modifier, with which
 concrete effects?

To any datatype, of course. The result should be:
1) Parameter is passed by value
2) Parameter modifications are forbidden by compiler

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Chad Berchek

Some thoughts on the meaning of const, constref, and constval, and how
they can usefully be applied:

My initial understanding of const was hazy. I have come to appreciate
that it is defined, but only in a very loose way. Instead of undefined I
should say ill-defined. I'm not entirely sure what some of the attacks
have been about, but I will acknowledge that I was not 100% sure about
const when I started. What I have said about it being unclear is
certainly true though. Let me explain how, and what I think a better
idea would be.

I wrote:

If we *knew* that const meant it would be by reference, then that
immediately eliminates the confusion in the case of ShortString
and records; modifying one instance through several references
affects them all, as expected. What the programmer says happens;
there can be no bug, except in the programmer's own knowledge.


Martin wrote:

We do know:
http://www.freepascal.org/docs-html/ref/refsu58.html#x135-14500011.4.4
A constant argument is passed by reference if its size is larger than
a pointer. It is passed by value if the size is equal or is less then
the size of a native pointer.


Jonas wrote:

A constant argument is passed by reference if its size is larger
 than a pointer. It is passed by value if the size is equal or is
 less then the size of a native pointer.

That part of the manual is wrong. What const does is by design
completely implementation-dependent


I should not say const is undefined. Actually I mean const is ambiguous;
sort of defined as undefined, in that: 1) with the current definition,
it changes by
platform, 2) the current definition is wrong anyway, and 3) it is
implementation dependent, which I interpret to mean it could change in
the future.

If the meaning of const is entirely implementation-dependent, and if I
interpret that correctly, I think we really cannot assume anything about
what exactly will happen with regard to the calling convention, which is
what I was worried about earlier.

Now, constref was intended for compatibility with other languages, but I
think it is a valuable addition to Pascal in its own right and that it
would be wise to use.

The hypothetical constval modifier is a natural corollary to this. In
the current implementation, if you were to pass a record to a procedure
for example, you have two choices: 1) pass it by value but have it be
non-const, 2) pass it as const, which might be by reference or value.
With constval and constref you would have the other two highly useful
choices: 1) pass by reference and it's const, 2) pass by value and it's
const. Without making assumptions about const, which I don't think we
can, these two options do not currently exist, so I think these new
keywords are a useful addition.

Some might say that it doesn't matter whether it is passed by value or
reference: if you pass it as const, either way you promise not to modify
it. See, that is my concern: what is IT? People have used other words,
but it ultimately comes down to: if you say the programmer promises not
to modify the thing passed as const, what thing *exactly* is that? A
variable, reference, or instance? With const, we don't really know. With
constref, it means you promise not to modify the memory location
(instance) pointed to by that reference. With constval it means
that you can change the memory location/instance that was
passed into the procedure, since the procedure is now using it's own
copy anyway; you just can't modify the instance that the procedure now
has it's own copy of.

One additional problem does arise. Constval implies that the
implementation is pass-by-value. However in many (I'd say most) cases it
is quite possible that we could be interested only in the semantics of
pass-by-value, not the implementation. So for AnsiStrings, neither
constref nor constval would be suitable. Constref would mean it must be
by reference, but we want by-value semantics. Constval would mean that
the string has to be copied to a separate memory location, which we
might not really care about, and is slow and wasteful.

So, I propose: don't have constval literally mean it is passed by value,
i.e.,
pushing the string onto the stack or copying it to a new memory
location. Instead, have constval defined as by-value *semantics*. In other
words, constval would indicate the meaning of the language, not the
implementation. It would not be a calling convention. It would not mean
the call would be by value; it would mean the semantics would be by
value. This is essentially what I originally thought const would mean
with AnsiStrings, though it turned out hazy.

The programmer must know the language and the compiler must implement the
language. How the compiler does that should not determine how the
program behaves. If constval is defined in semantics, not 
implementation, this means the compiler can still take whatever 
optimizations are possible as long as they do not break those semantics. 
So you would not have to actually copy strings, 

Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Jonas Maebe

On 11 Jul 2011, at 00:03, Daniël Mantione wrote:

 Calling conventions should in principle be eternally frozen. This includes 
 const, because for exampe a DLL compiled in version x can be imported by a 
 program compiled by version y.

That's indeed a good point.

 The fact that it has happened (for whatever reason) does not mean it is good 
 practise.

True.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Chad Berchek

On 7/10/2011 2:40 PM, Daniël Mantione wrote:

However, for a new calling convention (on an existing or a new
platform) it's completely up to the compiler designer what will be
passed as const and what will be passed as reference.


Agreed. That's why I say you can't really make assumptions: if you 
assume a certain platform, you can make a limited set of assumptions 
(very limited as I will show in a moment). However one of FPC's great 
features is its cross-platform power, so I don't want to make 
assumptions about the platform. Without assumptions about platform you 
can make even less assumptions about const.



Within a certain calling convention, the behaviour of const is
defined and will not change.


Even if the calling convention does not change, the semantics can, as 
currently implemented. Even within a single platform const is 
ill-defined. Consider the case of AnsiString. There are three cases as 
it is currently implemented:


1) Ref count  1 when passed as const parameter results in strict 
pass-by-value semantics
2) Ref count = 1 and you modify the original instance in-place results 
in the value of the parameter changing
3) Ref count = 1 and you modify the original reference such that the 
instance's ref count decreases to zero and it may crash or just give 
weird behavior


Although the programmer knows about reference counting, it is not 
expected for the programmer to know the details of the implementation, 
which can change. Therefore you cannot be 100% certain what the refcount 
is at any given time. And therefore you cannot be certain how const will 
be treated. We know the implementation will be pass-by-ref with no 
refcount change. The semantics could be pass-by-value, pass-by-ref, or 
just plain crashing, depending on details we cannot predict.



You Pascal code should be able to handle both value *and* reference.
 After all, with const you are leaving the decision to the compiler.
This is what it means in the end. Then your Pascal code should not
depend on specific behaviour.


Yes, I agree fully. That is the only choice with const. Constref, as it 
exists, with the addition of constval, provide a more precise form of 
expression on those occasions where one might feel the ambiguity of 
const is insufficient.


And before anyone says something, yes, I also understand that if you 
pass something as a const, you have to be prepared in case it is passed 
by reference, and you have to realize that if it is passed by reference, 
you have to promise not to modify the instance via another reference. 
That's OK.


I am a relative newcomer to Pascal, having used it about 1.5 years now. 
It was disturbing that something so important was not documented 
anywhere, and, in fact, there was documentation to the contrary. Aside 
from the lacking and sometimes incorrect documentation (I refer not only 
to FPC but to Delphi), I was surprised when the semantics of const 
AnsiStrings, which usually turn out to be pass-by-value, actually might 
not be in rare cases that are hard to predict.


Aside from good documentation (which Delphi is in need of too in this 
particular case), I am proposing constval in conjunction with the 
existing constref to provide greater expressive power and precision for 
the programmer.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Chad Berchek
Sorry for the additional post; I should have added this to my preceding 
message.


I just want to clarify: I am trying to be very careful to distinguish 
between implementation and semantics.


If my understanding is correct, AnsiString implementation is always 
pass-by-reference.


The problem is the programmer should be forced to stick to certain 
semantics, not a certain implementation. With const AnsiString, the 
implementation is consistently pass-by-ref, but the semantics can change 
as described in my previous message, depending on the instance's 
refcount when the procedure is invoked and what you may do with it while 
the procedure is running.


It has correctly been pointed out that you therefore can't make an 
assumption about what exactly a const AnsiString parameter will do; you 
just have to be prepared in either case, and if it turns out to be by 
reference, don't modify the instance via another reference.


I simply propose constref (existing) and constval (hyptothetical) for 
those who come across situations where more precise programming would be 
desired.


--- Implementation ---
I had a few ideas about implementation of constval, as I described it, 
for AnsiString. (Or, alternatively, a way to change the behavior of 
const, though this is no longer what I advocate.) These are all 
speculative. These are some ideas, basically, not assertions. Also my 
knowledge of how FPC works is limited as I've said before.


1. It seems that if a string is a (non-const) local variable it should 
be safe. I base this on the following reasoning:


a) In order to trigger the undesired behavior, you have to get an 
instance with a refcount of 1 which actually has more than one reference 
to it. The only way to do this is to pass a reference to an instance 
with a refcount of 1 to a function accepting a const AnsiString 
parameter. (Aside: The critical value is 1 because that determines 
whether copy-on-write happens and whether it gets freed the next time 
the refcount is decremented.)
b) Furthermore, you must be able to access the non-const reference at a 
higher scope (object, class, or global).
c) To do this, you could either have a higher-scope variable which you 
assign to a local variable, or vice versa.
d) If you do either of these, the refcount becomes 2 and the problem 
cannot occur.

e) The problem cannot be triggered passing a local variable.

2. Implementing 1 would require that the reference count update can be 
applied or not applied to a specific function depending how it's called. 
This could be done in two ways I'm thinking of:
a) Move the responsibility for updating the refcount to the caller. 
There are pros and cons to this idea. It could result in slightly larger 
code (because the refcount update and try-finally are in more places). 
However I think it could also speed things up *even more than the 
current implementation* because the refcount updates for several 
non-const strings could be combined into a single try-finally in the 
caller, rather than having one in each function.
b) Another possibility is to have two entry points to the function. The 
update of the refcount and try-finally would remain in the function, not 
the caller. However the caller could enter the function at either of two 
entry points. One would do the refcount update and set up the 
try-finally, whereas the other would skip to the code after that. I 
don't know if this is even possible. It seemed like something that might 
be doable with some tweaking when I was looking at the assembly code.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Max Vlasov
On Mon, Jul 11, 2011 at 4:45 AM, Chad Berchek ad...@vobarian.com wrote:

 1. It seems that if a string is a (non-const) local variable it should be
 safe. I base this on the following reasoning:


looks like it's not:

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;

  procedure SideEffectCall;
  begin
SetLength(S, 0);
  end;

  function CalcSomething(const T: string): integer;
  begin
Result:=0;
SideEffectCall;
MessageDlg(T, mtInformation, [mbOk], 0); // crash here
  end;

begin
  S:='12345678901234567890';
  S:=S + S;
  CalcSomething(S);
end;
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Hans-Peter Diettrich

Alexander Klenin schrieb:

On Mon, Jul 11, 2011 at 04:09, Hans-Peter Diettrich
drdiettri...@aol.com wrote:

If you want to introduce different keywords, then please different for
beforementioned cases. E.g.
constval x: integer; //all value-types
constref r: Trecord; //also ShortString
const??? o: TObject; //all references, except following
const??? s: AnsiString; //all managed types

I am not quite sure what are you asking here. Can you elaborate?

To which data type do you want apply your constval modifier, with which
concrete effects?


To any datatype, of course. The result should be:
1) Parameter is passed by value


How to pass objects by value?
Records with embedded AnsiStrings or other managed types?

DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-10 Thread Hans-Peter Diettrich

Chad Berchek schrieb:

I just want to clarify: I am trying to be very careful to distinguish 
between implementation and semantics.


Implementation is a very precise definition, which can be used to 
perfectly describe the semantics of a language. A verbose description of 
the semantics leaves too much room for misunderstandings, and commonly 
accepted formalisms are at least as hard to understand as implementation 
details, while not covering all aspects.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-09 Thread Hans-Peter Diettrich

Chad Berchek schrieb:

All the problems we've seen with const used in various contexts with 
different data types--AnsiString, ShortString, records, etc.--are the 
result of one fundamental problem, which is the language design. Const 
is not clearly defined. All problems mentioned stem from this.


IMO you should remove the C specs from your brain first, before you 
start using Pascal. Pascal const parameters are optimization hints in 
the first place, the write protection of parameters is a less important 
item instead.


Also C++ references are somewhat different from Pascal references, while 
both can make your code crash when the referenced object is modified or 
destroyed during subroutine execution - regardless of const or not.


Pascal ShortString and AnsiString have no counterpart in the C world. If 
you don't understand how to use these language features, then use PChar 
instead, to get back your C feeling with strings.


If you are incapable of learning how to write proper code, that allows 
for const optimization, you better keep your hands off it.



If we *knew* that const meant it would be by reference, then that 
immediately eliminates the confusion in the case of ShortString and 
records; modifying one instance through several references affects them 
all, as expected. What the programmer says happens; there can be no 
bug, except in the programmer's own knowledge.


When you know that const parameters typically are passed by reference, 
what else do you have to know, that's different from C/C++ behaviour?


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-09 Thread Max Vlasov
On Sat, Jul 9, 2011 at 4:13 AM, Martin f...@mfriebe.de wrote:
 On 09/07/2011 00:59, Max Vlasov wrote:

 On Sat, Jul 9, 2011 at 3:14 AM, Martinf...@mfriebe.de  wrote:

 function CRCConstString(constref Str: string): integer;
 does what you describ

 Hmm, it's interesting.. Some observations:
 - constref is implemented in 2.5.1, right? Unfortunately I can not
 test it right now in 2.4.2, it refuses to recognize it, but I I want
 to test it.
 - In LCL it used only with interfaces and TGuid's, no strings or other
 structures
 - there are not much information about constrefs in Lazarus, several
 posts, the largest part of them is yours, Martin :) so you're probably
 one of the few who really understand it  :)

 Well the LCL can't use it, if it's trunk only (except if IFDEFed). The LCL
 should compile with release fpc...

 See:
 http://wiki.lazarus.freepascal.org/FPC_New_Features_Trunk#Constref_parameter_modifier

 - See difference to normal const is  that it must be passed by
 reference.

 - Note (same as const) it is described as: This modifier means that the
 compiler can assume that the parameter is constant
 The assume means that the requirement for constant-ness goes above that
 what the compiler can enforce (that is: the compiler can enforce only the
 local var; but constant implies the value by any means of access)

 With what the compiler does today (afaik) none-constantness would not cause
 any harm (yet). Unless you count it as harm (and you should) that future FPC
 may (= is allowed to) compile your code (without any warning or hint) into
 an exe that behaves different.


Thanks for your notes, Martin. I compiled the trunk fpc (2.5.1) and
compile the example with constref

function TForm33.CRCConstRef(constref Str: string): integer;
var
  i: integer;
begin
  Result:=0;
  for i:=1 to Length(Str) do
Result:=Result + Ord(Str[i]);
end;

it worked, also the timing is exactly the same as for PString, so your
information (PString = constref Str) is indirectly confirmed. Btw,
Chad's example also worked

I understand that currently it works also because as you mentioned the
compiler doesn't apply special optimization, sure it could. But also
it's possible to forbid it for this special case. Since ansistring is
a special entity, not present in COM at all, so with regard to
standards it can be fully internal decision. Also since there are no
consref in Delphi as I suppose, they can't be the authority in this
regard :)

If everything it taken care of, apart from possibly global switch to
do const = constref aliasing, lcl also can gradually (when fpc 2.5.1
becomes requirement) replace const with constref in critical places
(for example when probable events can be fired). Sure this can break
inheritance, so just a thought to think about.

Max
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-09 Thread Thaddy

On 9-7-2011 3:29, Martin wrote:

On 09/07/2011 02:14, Chad Berchek wrote:
Specifically, the way const is now defined (or not...) is 
disturbing because it leaves out important details. In C++, you can 
pass by value or reference, or by pointer which is a value but is 
used to make references. But what's important is you _always_ know 
what it's going to do. If you pass something by reference and modify 
that instance via another reference, they're all going to change, 
because they are the same instance. And if you pass by value, it's 
the opposite. The point is, though, you always know what it's going 
to be.


Imagine if we took C++ and redefined the pass by reference syntax as 
the compiler might pass by value or reference, depending what it 
feels like. Result? Boom. Tons of carefully written code would 
suddenly break.



...
If we *knew* that const meant it would be by reference, then that 
immediately eliminates the confusion in the case of ShortString and 
records; modifying one instance through several references affects 
them all, as expected. What the programmer says happens; there can be 
no bug, except in the programmer's own knowledge.




We do know:
http://www.freepascal.org/docs-html/ref/refsu58.html#x135-14500011.4.4
A constant argument is passed by reference if its size is larger than 
a pointer. It is passed by value if the size is equal or is less then 
the size of a native pointer.


Of course if you want to rely on this, you must ensure the size of 
your type does ot change (a records definition can be chnaged, and 
that would have consequences for const param). But then, if you rely 
on it, but some compiler $IF and $FAIL in the code, to ensure it only 
compiles if your assumptions are met.


Personally I thing this page would be a good place to document the 
properties of const param with regards to ref-counted types...



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel
Isn't it time to cut this discussion short? const means do not modify! 
full stop! whatever by reference or value. The rest is bovine extrement.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-09 Thread Marcos Douglas
On Sat, Jul 9, 2011 at 12:40 PM, Thaddy tha...@thaddy.com wrote:
 Isn't it time to cut this discussion short? const means do not modify! full
 stop! whatever by reference or value. The rest is bovine extrement.

Not so fast.
As Hans-Peter Diettrich said: Pascal const parameters are
optimization hints in the first place, the write protection of
parameters is a less important item instead.

Is very important, for optimizations, we know if the parameter is
passed by reference or value... don't you think?

Marcos Douglas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-09 Thread Chad Berchek

Wow, thanks for the insults guys. I didn't realize I was so stupid.

You missed my point too, BTW. According to the link given:

A constant argument is passed by reference if its size is larger than a 
pointer.


So you always know what the size of a pointer is? If I have this record:

TMyRec = record
  I: Integer;
end;

Is that passed by value or ref? Is someone compiling on 32-bit or 64? 
You don't know, and neither does anyone. And that is my point about why 
having it defined is important.


I can't even remember the last time I used C++. My point in mentioning 
it was only to demonstrate by analogy what could happen if the same 
ambiguity present in the Pascal construct was present in other 
well-known languages.


All the argument that such bug could exist with shortstrings and 
records as well is because nobody can say for sure whether they are 
supposed to be passed by value or by ref--it could be either. With 
constref, there is no ambiguity. You know it will be by ref, hence there 
is no question as to whether it's a bug. Otherwise it's just a matter of 
opinion.


I guess my brain is way to tiny to get past the notion that a write 
once, compile anywhere programming language should be defined in such a 
way that the meaning of the program doesn't spontaneously change 
depending on the compilation platform.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-09 Thread Jonas Maebe

On 09 Jul 2011, at 03:29, Martin wrote:

 We do know:
 http://www.freepascal.org/docs-html/ref/refsu58.html#x135-14500011.4.4
 A constant argument is passed by reference if its size is larger than a 
 pointer. It is passed by value if the size is equal or is less then the size 
 of a native pointer.

That part of the manual is wrong. What const does is by design completely 
implementation-dependent (except for cdecl/cppdecl routines, where it behaves 
the same as in C/C++, and for mwpascal routines, where it behaves the same as 
in MetroWerks Pascal). And yes, this is different from the meaning of const C 
and C++ (which is why the meaning is specified separately there). And yes, this 
means that it can be unsafe if you pass global variables as const and the 
modify them in the called routine, and that every objection voiced already 10 
times in this thread applies. That is how const has always worked since it was 
introduced in Turbo Pascal. And no, that does not mean this is ideal, but 
rewriting the entire const handling is not going to happen.

Alternatives (such as constref) can be used, and checks can be added, etc, but 
in general const has always meant in FPC (and Delphi) and will probably always 
mean I promise that I will not modify this parameter in any way, please help 
me as far as you can in preventing accidental modifications, and apart from 
that you can generate any code you want based on that assumption.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-09 Thread Jonas Maebe

On 09 Jul 2011, at 18:41, Jonas Maebe wrote:

 That part of the manual is wrong. What const does is by design completely 
 implementation-dependent (except for cdecl/cppdecl routines, where it behaves 
 the same as in C/C++, and for mwpascal routines, where it behaves the same as 
 in MetroWerks Pascal). And yes, this is different from the meaning of const C 
 and C++ (which is why the meaning is specified separately there). And yes, 
 this means that it can be unsafe if you pass global variables as const and 
 the modify them in the called routine, and that every objection voiced 
 already 10 times in this thread applies. That is how const has always worked 
 since it was introduced in Turbo Pascal. And no, that does not mean this is 
 ideal, but rewriting the entire const handling is not going to happen.

And yes, that should all be mentioned in the manual.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-09 Thread Flávio Etrusco
On Sat, Jul 9, 2011 at 6:55 PM, Hans-Peter Diettrich
drdiettri...@aol.com wrote:
 Flávio Etrusco schrieb:

 Isn't this unfortunately encumbered by patents?
 http://wiki.winehq.org/CompilerExceptionSupport

 http://yro.slashdot.org/story/05/05/12/1947213/Winelib-Hobbled-by-Exception-Handling-Patent

 Software patents should not be a problem outside the USA. A nice try, but
 unimportant for non-resident free software writers and distributors.

 DoDi


I know that, I just wanted to raise the issue, since nobody raised it
and I don't/didn't whether all FPC developers lived outside US.
I'm brazilian (and live in Brazil) and this is - for now... - not an
issue here either.

-Flávio
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Daniël Mantione



Op Thu, 7 Jul 2011, schreef Chad Berchek:

The problem comes down to the specs though, or rather the lack thereof. As I 
have searched the web and read some docs at Embarcadero, things have only 
become more ambiguous.


You are looking in the wrong places. Both Turbo Pascal and Delphi came 
with a language guide that describe the desired behaviour in deep detail.


Daniël___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug (What nexy)

2011-07-08 Thread Martin

On 08/07/2011 11:05, Jonas Maebe wrote:

On 08 Jul 2011, at 05:51, Chad Berchek wrote:
I'm more interested now in a solution. The solutions I've seen so far 
have potential, but in my opinion most of them seem like they are 
more complex, would be more overhead, and produce worse performance 
than just getting rid of the const optimization.


The main proposals I've seen were
a) treat const string parameters the same as value parameters (i.e., 
get rid of the current const behaviour)
b) the same as a), combined with a very conservative heuristic to 
apply the optimization in case there can be no side effects. I.e., in 
case there is not a single function call and not a single indirect 
write (var parameter, pointer, global variable, dynamic array, ...) to 
any string or anything that might be somehow aliased to a string 
passed as parameter to the current routine
c) keep the current behaviour, but add functionality to the compiler 
to help debug problems that can occur as a result of problems that can 
occur as a result of this behaviour



Actually I think you can describe that as 3 independent proposals:

1) Add a compiler switch or directive to disable constbehaviour for 
ref counted types (e.g. simply ignore const for 
string/dyn-array/interface params; Actually downgrade, still prevent 
assignment to local var)
2) Add automatic optimization of dropping ref-count and exception frame, 
if the compiler can prove it to be save (e.g.  no calls to any other 
code...). This can happen completely independent of either the present 
or meaning of const.

3) Add safety checks (similar to range checks)

1)
The only thing I can see, is that future optimization, added to 
const-param (of all types, e.g also records, etc) can introduce 
problems, when the value of the const param is indirectly changed, and 
that may lead to further requests of what const should or should not do. 
It may be needed to draw a line, and point out that const will always 
have some dangers. (Apparently with such a ignore-it-fix not any more 
for ansistrings (copy on write), but still for dyn arrays (also ref 
counted)).
Anyway if the extend off that switch is well defined, it may be worth 
having. IMHO better as compiler directive, that would allow to put it 
into the code, and make sure behaviour is stabel (rather than behaviour 
might change, if a compiler switch is used)


2)
Depends, on someone writing and contributing it. Mostly unrelated to the 
discussion.


3)
Might not only help to fix issues, but might also create awareness.

However, looking at the generated assembly, I can't believe there 
isn't a more efficient way to handle the implicit try-finally. It 
feels to me like that is where the problem is. There is a lot of code 
and several function calls that go into implementing that implicit 
'finally' block. There's got to be some way to decrement the refcount 
even when there are exceptions but without so much overhead. It would 
require changes to the exception handling mechanism though. Here my 
knowledge runs out.


The main problem here is that FPC's exception handling is based on 
setjump/longjump. This technique has a relatively high overhead for 
try, but low overhead when an exception actually occurs (of course, 
since exceptions are supposed to happen only exceptionally, that's not 
a really good selling point). The main reason we use it is because 
it's easy to implement.




For implicit exception (so long as there purpose is only to decrease 
ref-counts (and free the data if 0 reached), there is another solution.


If an exception frame already exists (even if on a higher stackframe), 
and the compiler can detect that it does exist:
then instead of creating an exception frame for the current stackframe, 
all the variables that need refcount decrement, can be added to a list. 
This list can be processed by the exception handler, before any other 
code executes. The draw back is, that memory needs to be allocated for 
this list.



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Sven Barth

Am 08.07.2011 12:05, schrieb Jonas Maebe:

However, looking at the generated assembly, I can't believe there
isn't a more efficient way to handle the implicit try-finally. It
feels to me like that is where the problem is. There is a lot of code
and several function calls that go into implementing that implicit
'finally' block. There's got to be some way to decrement the refcount
even when there are exceptions but without so much overhead. It would
require changes to the exception handling mechanism though. Here my
knowledge runs out.


The main problem here is that FPC's exception handling is based on
setjump/longjump. This technique has a relatively high overhead for
try, but low overhead when an exception actually occurs (of course,
since exceptions are supposed to happen only exceptionally, that's not a
really good selling point). The main reason we use it is because it's
easy to implement.

A better approach would be to use SEH-based exception handling (which
has no overhead at all for try, and a high overhead in case an
exception occurs), but that woud require
a) support for generating EH frames for all platforms (it's currently
only supported for a number of i386 and x86-64 platforms)
b) support for parsing EH frames on all platforms and performing
exception handling based on that

This is definitely something we want, but nobody has found the time yet
to implement it.


Around a year ago I've experimented with using SEH on Windows (I have 
not reached a working state back then). It's on my list to revive this 
again, but before that I want to have Delphi compatible generics and 
extended RTTI with attributes working :D


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug (What nexy)

2011-07-08 Thread Hans-Peter Diettrich

Martin schrieb:

c) keep the current behaviour, but add functionality to the compiler 
to help debug problems that can occur as a result of problems that can 
occur as a result of this behaviour


Concrete: add means to ignore const with managed types.

Further debugging aids as far as feasable. Do we want to make FPC an 
outstanding compiler, WRT bug hunting? IMO *not* a realistic goal.




Actually I think you can describe that as 3 independent proposals:

1) Add a compiler switch or directive to disable constbehaviour for 
ref counted types (e.g. simply ignore const for 
string/dyn-array/interface params; Actually downgrade, still prevent 
assignment to local var)


+1

2) Add automatic optimization of dropping ref-count and exception frame, 
if the compiler can prove it to be save (e.g.  no calls to any other 
code...). This can happen completely independent of either the present 
or meaning of const.


~ [people will point at you if it doesn't work perfectly :-]


3) Add safety checks (similar to range checks)


As a debug feature only, on demand (debugging memory manager?)


Most people don't have problems with const, according debug features are 
*not* an urgent requirement.


I only agree that a *quick workaround* (global ignore const option) is 
highly desireable (a *must*) for the rare (but real) cases where it can 
make runtime errors disappear.


Extended debug features are not so important, because code with such 
problems typically suffers from *general* problems, which suggest a 
change of the personal coding style. A compiler can prevent an user from 
shooting himself into one foot, at best, but not prevent him from 
shooting himself into other limbs :-]





3)
Might not only help to fix issues, but might also create awareness.


This may apply to newbies, but IMO will be ignored by people which 
*believe* that they are superior coders, maybe from practice in other 
languages. A collection of suggested design patters (resource 
protection, object ownership...) would be nice - in detail for pointing 
people with coding style problems to. We could add to that collection 
all demo code, that forces unexpected exceptions, together with a safe 
version of the same code, that eliminates the demonstrated problem.




If an exception frame already exists (even if on a higher stackframe), 
and the compiler can detect that it does exist:
then instead of creating an exception frame for the current stackframe, 
all the variables that need refcount decrement, can be added to a list. 
This list can be processed by the exception handler, before any other 
code executes. The draw back is, that memory needs to be allocated for 
this list.


IMO this is what the compiler already does, or should do - an implicit 
try-finally block with a list of variables to be finalized on exit of a 
subroutine (used also in stack unwinding after an exception). One should 
not confuse try-except (*handling* exceptions) and try-finally 
(guaranteed *cleanup*).


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Den Jean
On Friday 08 July 2011 12:05:02 Jonas Maebe wrote:
 The main problem here is that FPC's exception handling is based on  
 setjump/longjump. This technique has a relatively high overhead for  
 try, but low overhead when an exception actually occurs (of course,  
 since exceptions are supposed to happen only exceptionally, that's not  
 a really good selling point). The main reason we use it is because  
 it's easy to implement.
 
 A better approach would be to use SEH-based exception handling (which  
 has no overhead at all for try, and a high overhead in case an  
 exception occurs), but that woud require
I strongly prefer the current situation where the occurrence of 
exceptions does not incur an important extra overhead compared to
the nominal situation.

In the type of applications I write (Air Traffic Control Radar Screens,
Electronic Strips and System Interfaces) it is considered good practice 
to catch exceptions in every procedure because it is a must that 
the applications always survive and continue to provide the remaining,
not affected services.(graceful degradation principle)

I do not want any discussions whether catching exceptions is good or not.
If someone thinks otherwise, I do not care at all, do not bother me or 
this mailing list. 

However what is imperative is that when many exceptions occur, there should 
not be a mayor performance penalty. One of the reasons I use languages such 
Pascal and Ada for this type of applications, is that they are very fast, 
(though I also have foreseen code to shutdown services with too many problems 
in a given time frame). So I beg you to leave exceptions as is (please :-)). 

kind regards,

Den Jean
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Martin

On 09/07/2011 00:09, Max Vlasov wrote:

The answer is indirect referencing. it's a workaround that probably
will solve the problem, but I must admit that I don't know what is the
exact performance price. The compiler when it detects const s:
ansistring could switch to passing not the actual address of the
string, but the address of the variable that holds it. In other words
passing PString instead of string. In this case no reference counting
or exception frame is probably created and at the same time, if the
used string is reallocated occasionally because of a side change, the
code will not fail because it will just automatically use the new
modified address.



function CRCConstString(constref Str: string): integer;

does what you describe

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Max Vlasov
On Sat, Jul 9, 2011 at 3:14 AM, Martin f...@mfriebe.de wrote:
 On 09/07/2011 00:09, Max Vlasov wrote:

 The answer is indirect referencing. it's a workaround that probably
 will solve the problem, but I must admit that I don't know what is the
 exact performance price. The compiler when it detects const s:
 ansistring could switch to passing not the actual address of the
 string, but the address of the variable that holds it. In other words
 passing PString instead of string. In this case no reference counting
 or exception frame is probably created and at the same time, if the
 used string is reallocated occasionally because of a side change, the
 code will not fail because it will just automatically use the new
 modified address.


 function CRCConstString(constref Str: string): integer;

 does what you describe


Hmm, it's interesting.. Some observations:
- constref is implemented in 2.5.1, right? Unfortunately I can not
test it right now in 2.4.2, it refuses to recognize it, but I I want
to test it.
- In LCL it used only with interfaces and TGuid's, no strings or other
structures
- there are not much information about constrefs in Lazarus, several
posts, the largest part of them is yours, Martin :) so you're probably
one of the few who really understand it  :)

If constref is what you said , some quick fix for those who's scary
of the current const behavior could  be iintroducing a setting in fpc
that forces all const to be constrefs.

Max
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Martin

On 09/07/2011 00:59, Max Vlasov wrote:

On Sat, Jul 9, 2011 at 3:14 AM, Martinf...@mfriebe.de  wrote:

function CRCConstString(constref Str: string): integer;
does what you describ

Hmm, it's interesting.. Some observations:
- constref is implemented in 2.5.1, right? Unfortunately I can not
test it right now in 2.4.2, it refuses to recognize it, but I I want
to test it.
- In LCL it used only with interfaces and TGuid's, no strings or other
structures
- there are not much information about constrefs in Lazarus, several
posts, the largest part of them is yours, Martin :) so you're probably
one of the few who really understand it  :)
Well the LCL can't use it, if it's trunk only (except if IFDEFed). The 
LCL should compile with release fpc...


See: 
http://wiki.lazarus.freepascal.org/FPC_New_Features_Trunk#Constref_parameter_modifier


- See difference to normal const is  that it must be passed by 
reference.


- Note (same as const) it is described as: This modifier means that the 
compiler can assume that the parameter is constant
The assume means that the requirement for constant-ness goes above 
that what the compiler can enforce (that is: the compiler can enforce 
only the local var; but constant implies the value by any means of access)


With what the compiler does today (afaik) none-constantness would not 
cause any harm (yet). Unless you count it as harm (and you should) that 
future FPC may (= is allowed to) compile your code (without any 
warning or hint) into an exe that behaves different.


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Chad Berchek

Martin wrote:

- See difference to normal const is  that it must be passed by
reference.


I had not read about it before, but I think constref is a huge step in 
the right direction. It eliminates my fundamental grief with the current 
implementation.


Specifically, the way const is now defined (or not...) is disturbing 
because it leaves out important details. In C++, you can pass by value 
or reference, or by pointer which is a value but is used to make 
references. But what's important is you _always_ know what it's going to 
do. If you pass something by reference and modify that instance via 
another reference, they're all going to change, because they are the 
same instance. And if you pass by value, it's the opposite. The point 
is, though, you always know what it's going to be.


Imagine if we took C++ and redefined the pass by reference syntax as 
the compiler might pass by value or reference, depending what it feels 
like. Result? Boom. Tons of carefully written code would suddenly break.


It is OK for implementation details to be unspecified. That is how they 
should be--but only if they are in fact implementation details. If they 
affect the *meaning* of the program, they have to be defined as part of 
the language. That's what bothers me. The behavior of const is something 
that does affect the behavior of the program, but it is undefined. 
/Usually/ when you pass a record as const it will by by reference, but 
maybe not. Ditto for other types.


All the problems we've seen with const used in various contexts with 
different data types--AnsiString, ShortString, records, etc.--are the 
result of one fundamental problem, which is the language design. Const 
is not clearly defined. All problems mentioned stem from this.


If we *knew* that const meant it would be by reference, then that 
immediately eliminates the confusion in the case of ShortString and 
records; modifying one instance through several references affects them 
all, as expected. What the programmer says happens; there can be no 
bug, except in the programmer's own knowledge.


This precision of language is closely tied with the testing approach 
several people have mentioned. The testing approach is that you run 
the program with the const optimization on, and, if it works, great, and 
if not, turn the optimization off.


I greatly disagree with this approach. Testing is very important, 
certainly. But you can only ever test a tiny fraction of real world 
scenarios. Ultimately you are much better off if you can mentally verify 
that the program is unconditionally *correct*. That is why I cannot 
accept the ambiguous const feature, because it is impossible to 
theoretically prove that the program is correct, which is something I 
try to do as much as possible.


I applaud the notion of constref. I think it should be used everywhere 
as long as Delphi compatibility is not required.


The difference is slight. In many (but not all--and that's the key) 
cases using const or constref would result in the same assembly, if my 
understanding is correct. What's really important is that it allows the 
programmer to reason logically about a piece of code without mysteries 
popping up.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-08 Thread Martin

On 09/07/2011 02:14, Chad Berchek wrote:
Specifically, the way const is now defined (or not...) is disturbing 
because it leaves out important details. In C++, you can pass by value 
or reference, or by pointer which is a value but is used to make 
references. But what's important is you _always_ know what it's going 
to do. If you pass something by reference and modify that instance via 
another reference, they're all going to change, because they are the 
same instance. And if you pass by value, it's the opposite. The point 
is, though, you always know what it's going to be.


Imagine if we took C++ and redefined the pass by reference syntax as 
the compiler might pass by value or reference, depending what it 
feels like. Result? Boom. Tons of carefully written code would 
suddenly break.



...
If we *knew* that const meant it would be by reference, then that 
immediately eliminates the confusion in the case of ShortString and 
records; modifying one instance through several references affects 
them all, as expected. What the programmer says happens; there can be 
no bug, except in the programmer's own knowledge.




We do know:
http://www.freepascal.org/docs-html/ref/refsu58.html#x135-14500011.4.4
A constant argument is passed by reference if its size is larger than 
a pointer. It is passed by value if the size is equal or is less then 
the size of a native pointer.


Of course if you want to rely on this, you must ensure the size of your 
type does ot change (a records definition can be chnaged, and that would 
have consequences for const param). But then, if you rely on it, but 
some compiler $IF and $FAIL in the code, to ensure it only compiles if 
your assumptions are met.


Personally I thing this page would be a good place to document the 
properties of const param with regards to ref-counted types...



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Florian Klaempfl
Am 07.07.2011 08:35, schrieb Alexander Klenin:
 As further support for #1, consider: With a class, you do not have to pass
 it to a procedure as var, but when you modify the instance, you modify the
 same instance as was passed to the procedure. That is how classes work.
 Having a variable point to the same object as another variable does in fact
 mean it's the same instance, the same object. That is Object Pascal's object
 model. But with strings, if you want to modify the string in a procedure and
 have that affect the argument initially passed to the procedure you *have*
 to use var. That alone should be convincing evidence that the programmer is
 always supposed to be able to assume that unique variables are unique
 instances for automatically managed strings and arrays.
 This is also a good argument which I omitted before in the interests of 
 brevity.
 
 Put in another words, current const string implementation honors the
 implicit contract of
 adding const in front of the string parameter cancels refcounting,
 at the cost of breaking the implicit contract of refcounted values
 are indistinguishable
 from simple values (except maybe in performance).

As I have shown before in this thread, non ref. counted values e.g.
shortstrings are affected by the same problem.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Thu, Jul 7, 2011 at 17:45, Florian Klaempfl flor...@freepascal.org wrote:
 Put in another words, current const string implementation honors the
 implicit contract of
 adding const in front of the string parameter cancels refcounting,
 at the cost of breaking the implicit contract of refcounted values
 are indistinguishable
 from simple values (except maybe in performance).

 As I have shown before in this thread, non ref. counted values e.g.
 shortstrings are affected by the same problem.

And as per Chad's reply (and agree with his logic), this is not so.

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread michael . vancanneyt



On Thu, 7 Jul 2011, Chad Berchek wrote:



Michael wrote:

You can always fool the compiler. The compiler trusts you and assumes
that what you tell her is true...


Yes, of course you can always fool the compiler, it just shouldn't be
the other way around. The example you gave is very different for one
very important reason: you show using explicit allocating and freeing of
an object. With strings, the programmer does not, and cannot, explicitly
allocate or deallocate the resources, and the problem lies in the
behavior of the automatic allocation and deallocation. Thus there is
nothing in common between this example and the problem at hand.


Nonsense.

The example is reproducible just as well with shortstrings or plain records,
where there is no 'allocation' or 'Deallocation'. Such examples can wreak
havoc just as much. With the example I showed, it's just much more clear.
(i.e. a straight crash)

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Mattias Gaertner
On Thu, 07 Jul 2011 00:15:54 -0500
Chad Berchek ad...@vobarian.com wrote:

[...]
 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).

It is a general problem of languages supporting pointers that you can
change const data. Const can never protect 100%. 
Maybe this should be mentioned more prominent in the docs, probably with
some examples, although I don't know where a good place is.

And it is a general problem that compile time checks/protection only
works for a limited scope. Code outside the scope can not be checked by
the compiler. A const parameter is only checked for the scope of the
body. If you leave the body then the compiler can not help.
And sharing memory (s1:=s2) is a run time problem, which means it
is outside of the compiler scope too.

 
[...]
 Yes, of course you can always fool the compiler, it just shouldn't be
 the other way around. The example you gave is very different for one
 very important reason: you show using explicit allocating and freeing of
 an object. With strings, the programmer does not, and cannot, explicitly
 allocate or deallocate the resources, and the problem lies in the
 behavior of the automatic allocation and deallocation. Thus there is
 nothing in common between this example and the problem at hand.

Why do you think so? You can explicitly allocate and deallocate using
SetLength, UniqueString, ...

 
[...]
 Florian wrote:
  It affects more types, even shortstring suffers from it
 
 I must respectfully disagree. In the case of shortstring, the value of 
 the const parameter does get modified, but that is to be expected. If my 
 understanding is correct (and I'm open to be corrected), the semantics 
 of ShortString are different. With AnsiString, assigning one string 
 variable to another is supposed to create the illusion that they are 
 unique instances.

Yes, but it is documented that it is only an illusion.
AnsiStrings share data.


 Hence there is copy-on-write. With short strings, 
 assigning one to another literally means they are the same instance. 
 Again this comes back to the difference between instance and variable, 
 and the illusion implicit in AnsiString and dynamic arrays, which I 
 think is not the case with ShortString (but again I could be wrong).
 
 The problem at issue here is the fact that the compiler can actually 
 free memory prematurely. In the case of shortstring, it won't crash. 

A crash is just a boundary check by the OS.
With Ansistring the crash happens some time after the real bug. And it
does not need to manifest as a crash. The same happens if you do that
with shortstrings or records or whatever.
As Florian already wrote this belongs to a whole category of nasty bugs
and there are tools to find them.


[...]
 Now I will acknowledge that const can be used in certain limited 
 situations without harm. 

The term limited is pretty wrong. For example const string is
used at several thousands places in the lazarus and fpc sources. And
afaik they were used wrong less than ten times. In many cases it was
right and became wrong, because some called function changed.


[...]
 To summarize:
 
 1. To the programmer, each AnsiString and dynamic array variable is 
 supposed to be unique, i.e., after doing A := B, modifying A does not 
 affect B and vice versa.

That's only true for a limited set of functions and operators.
For example using Move on the characters will modify both.

 
 2. The fact that multiple variables (or parameters) actually can refer 
 to a single instance is an implementation optimization. That is of no 
 concern to the programmer.

Huh?
It is one of the main reasons to use ansistring instead of shortstring.
And many implementations rely on the runtime difference O(1) vs O(n).


 The optimization is implemented by the 
 combination of reference counting and copy-on-write.
 
 3. The programmer cannot be aware of what the compiler decides to do 
 regarding how it implements reference counting and copy-on-write. The 
 programmer should simply know that unique variables are unique instances 
 for all practical purposes (except var parameters obviously, since that 
 is the whole point of having to declare it var).

The 'all practical purposes' is not clear.
I guess some people think a Move is a practical function.

 
 4. If the programmer cannot be aware of when an instance is shared with 
 multiple variables, an implicit contract that the programmer cannot 
 modify other variables 

Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Hans-Peter Diettrich

Chad Berchek schrieb:


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.


*Aliasing* is a common problem, not restricted to const parameters.

A subroutine may e.g. free a global object, and replace it by its 
argument. Calling this subroutine with that global object results in an 
invalid reference in the global variable.



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.


In C const has several meanings, comparison with other languages is 
not a good idea.


In OPL const means that the argument will not be altered inside the 
subroutine, so that the compiler can apply some optimizations[1]. That's 
all. The compiler *can* check for e.g. illegal writes to an const 
parameter, but there is no such *obligation*, and it's known that the 
compiler can be fooled by trickery, in any language.


[1] E.g. const record parameters can be passed by reference, instead of 
passing a copy (by value) to the subroutine. Managed types can be passed 
without refcounting and associated try-finally constructs. But there 
exists no guarantee, which compiler will apply what optimization, under 
which conditions.



I do not defend critical optimizations in an compiler. E.g. it's known 
that managed types with a RefCount of zero should not be passed as const 
parameters, *when* inside the subroutine the RefCount can be increased 
and decreased again. Here the compiler may have a chance to report an 
*possibly* inappropriate use of const.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 07:51, Alexander Klenin wrote:

On Thu, Jul 7, 2011 at 17:45, Florian Klaempflflor...@freepascal.org  wrote:

Put in another words, current const string implementation honors the
implicit contract of
adding const in front of the string parameter cancels refcounting,
at the cost of breaking the implicit contract of refcounted values
are indistinguishable
from simple values (except maybe in performance).

As I have shown before in this thread, non ref. counted values e.g.
shortstrings are affected by the same problem.

And as per Chad's reply (and agree with his logic), this is not so.



Well  it's not as obvious)

In Florian's  example the const param follows the value of the 
original variable (so yes it does something that is unexpected)
But with short string it does not crash. there is no ref count going 
wrong, there is no memory being freed while still in use.


Yet he is 100% right it's the same problem, the same error, and as severe.

Because the behaviour is not guaranteed.
The compiler (in future versions) could make optimizations knowing that 
the const s: shortstring (or const x: sometype) doesn't change.


And that means, in future such code could behave different or even 
crash, only by change of content (even if memory is not freed).
Hence yes, it is as severe as with ansistrings. It only is not yet as 
visible.



Here is the example as provided by Florian:

var
  s : shortstring;

procedure p(const s1 : shortstring);
  begin
s:='Ops';
writeln(s1);
  end;

begin
  s:='Hello world';
  p(s);
end.



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Mattias Gaertner
 
 

 Martin f...@mfriebe.de hat am 7. Juli 2011 um 12:20 geschrieben:

  On 07/07/2011 07:51, Alexander Klenin wrote:
 [...]
   As I have shown before in this thread, non ref. counted values e.g.
   shortstrings are affected by the same problem.
   And as per Chad's reply (and agree with his logic), this is not so.
 
 
  Well  it's not as obvious)
 
  In Florian's  example the const param follows the value of the
  original variable (so yes it does something that is unexpected)
  But with short string it does not crash. there is no ref count going
  wrong, there is no memory being freed while still in use.
 
  Yet he is 100% right it's the same problem, the same error, and as severe.
 
  Because the behaviour is not guaranteed.
  The compiler (in future versions) could make optimizations knowing that
  the const s: shortstring (or const x: sometype) doesn't change. 
You don't need the future. You can already create a crash using const
shortstring:
 
 
{$mode objfpc}{$H+}
 uses Classes;
 var
   s: shortstring = '';
   o: TStringList = nil;

 procedure DoSomething(const h: shortstring);
 begin
   if h'' then
     o:=TStringList.Create; // not called, because s=h=''
   s:='A';
   if h'' then
     writeln(o.Count); // called, because now s=h='A' = crash
 end;

 begin
   DoSomething(s);
 end.
 
 

 [...]

 Mattias___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 11:43, Mattias Gaertner wrote:


You don't need the future. You can already create a crash using const 
shortstring:




Indeed, thanks for the example.

And with this example there is another potential issue arising from not 
honouring the contract of const.


The behaviour of such code may change at random depending on fpc-version 
or optimization. Future versions of fpc could cahce the result of 
h'' (as this expression is constant too), and re-use it in the 2nd IF.
So mis-honouring the rules of how to use const does not only lead to 
potential crashes, but it also leads to code that has no defined 
behaviour, and may lead to completely random results.


This means the current behaviour with ansistring is absolutely right. It 
is only a consequence of the behaviour already observed with other types.





{$mode objfpc}{$H+}
uses Classes;
var
  s: shortstring = '';
  o: TStringList = nil;

procedure DoSomething(const h: shortstring);
begin
  if h'' then
o:=TStringList.Create; // not called, because s=h=''
  s:='A';
  if h'' then
writeln(o.Count); // called, because now s=h='A' = crash
end;

begin
  DoSomething(s);
end.

[...]


Mattias


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread michael . vancanneyt



On Thu, 7 Jul 2011, Mattias Gaertner wrote:


 
 

Martin f...@mfriebe.de hat am 7. Juli 2011 um 12:20 geschrieben:

 On 07/07/2011 07:51, Alexander Klenin wrote:
[...]
  As I have shown before in this thread, non ref. counted values e.g.
  shortstrings are affected by the same problem.
  And as per Chad's reply (and agree with his logic), this is not so.


 Well  it's not as obvious)

 In Florian's  example the const param follows the value of the
 original variable (so yes it does something that is unexpected)
 But with short string it does not crash. there is no ref count going
 wrong, there is no memory being freed while still in use.

 Yet he is 100% right it's the same problem, the same error, and as severe.

 Because the behaviour is not guaranteed.
 The compiler (in future versions) could make optimizations knowing that
 the const s: shortstring (or const x: sometype) doesn't change. 
You don't need the future. You can already create a crash using const
shortstring:
 
 
{$mode objfpc}{$H+}
uses Classes;
var
  s: shortstring = '';
  o: TStringList = nil;

procedure DoSomething(const h: shortstring);
begin
  if h'' then
    o:=TStringList.Create; // not called, because s=h=''
  s:='A';
  if h'' then
    writeln(o.Count); // called, because now s=h='A' = crash
end;

begin
  DoSomething(s);
end.


Sigh

That's what I've been saying all along. You don't even need strings for it.
Plain records and integers will do it just as well.

Michael.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Thu, Jul 7, 2011 at 22:10,  michael.vancann...@wisa.be wrote:
 Sigh

 That's what I've been saying all along. You don't even need strings for it.
 Plain records and integers will do it just as well.

Well, I am sorry, but do you all (not only Michael, I'm just
responding to the last mail in the thread)
really think I am stupid enough to not know it?
It is quite understandable that FPC developers want to defend the status quo,
but can you please do it by responding to the argument OP and I actually make?

I'll re-iterate again:
1) The reference counting is not just an optimization, it is also a
memory management technique,
an important concept which is aimed at providing simple value
semantics for heap-allocated structures,
and insulating the programmer from memory allocation details.
If programmer does not do anything obviously dangerous like direct
memory access,
using strings is guaranteed not to cause a whole class of memory errors,
like leaks, double-frees and access-after-free.
Current const string implementation breaks this guarantee for the
sake of minor optimization.
It is actually quite ridiculous: var s: String *is now safer* than
const s: String,
because the former can not cause AV, but the latter can.
2) Also, there is a separate-but-related issue that Object Pascal
traditionally conflates
const and reference semantics in parameters. It would be
significantly better to have
separate const and constref attributes, but I guess it is much too late.
Nevertheless, currently there are two groups of types in FPC, simple types
like numerics for which const acts like passing by value,
and complex types for which const acts like passing by reference.
Note that currently const string *is passed by value*,
*except when the reference count equals to 1*, when it suddenly
behaves as if passed by reference.

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread michael . vancanneyt



On Thu, 7 Jul 2011, Alexander Klenin wrote:


On Thu, Jul 7, 2011 at 22:10,  michael.vancann...@wisa.be wrote:

Sigh

That's what I've been saying all along. You don't even need strings for it.
Plain records and integers will do it just as well.


Well, I am sorry, but do you all (not only Michael, I'm just
responding to the last mail in the thread)
really think I am stupid enough to not know it?
It is quite understandable that FPC developers want to defend the status quo,
but can you please do it by responding to the argument OP and I actually make?


The problem is your understanding of const.

The declaration

Procedure DoSomething(const A : Type);

means:

  YOU promise not to change A inside DoSomething.

Based on this promise, the compiler may decide to do some optimization.
It will also warn you if it detects inside the code that you break your promise.

The declaration

Procedure DoSomething(const A : Type);

does NOT mean:

  The compiler promises that A does not change inside DoSomething.

You seem to think that this should be the case. Well, it is not the case.

Const is an aid from you to the compiler. Not an aid from the compiler to you.

As soon as you understand this subtle difference, the problem disappears.

Michael.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 12:42, Alexander Klenin wrote:


I'll re-iterate again:
1) The reference counting is not just an optimization, it is also a
memory management technique,
an important concept which is aimed at providing simple value
semantics for heap-allocated structures,
and insulating the programmer from memory allocation details.
If programmer does not do anything obviously dangerous like direct
memory access,
using strings is guaranteed not to cause a whole class of memory errors,
like leaks, double-frees and access-after-free.
Current const string implementation breaks this guarantee for the
sake of minor optimization.
It is actually quite ridiculous: var s: String *is now safer* than
const s: String,


I do think Florians, or Mattias  example are relevant.
Let's for a moment ignore the const ansistring issue.

The 2 examples prove, that even with const i : SomeRecord, your code 
can crash for none obvious reasons, IF you break the promise, not to 
modify the value of I, by modifying the value that you passed in.


That is:
 const x: sometype for any type (with the exception maybe of those , 
that are passed by value) can lead to undefined behaviour and/or 
crashes, if the promise of const is broken.


If the above statement can be agreed on (and the examples show this), 
then why should the const ansi string be a bigger issue?


Yes, the const ansi string breaks the rules that ought to be provided by 
ref-counting.
But it only breaks this ref-count promise, for code that is already 
unsave, even if ref-counting was in place.


As I have stated in my reply to Mattias, future fpc, could do all short 
of optimizations, caching the result of expressions that use only 
constants, and const param = the result of such expressions has to be 
constant too.
So even if ref-counting was in place. The code was unsafe, because it's 
behaviour is not defined, and it's results could randomly change in future.


Given that the very same code would still be unsafe, even if ref 
counting was there, then why put ref-counting in there?





because the former can not cause AV, but the latter can.
2) Also, there is a separate-but-related issue that Object Pascal
traditionally conflates
const and reference semantics in parameters. It would be
significantly better to have
separate const and constref attributes, but I guess it is much too late.


actually constref exists.
but what you seem to want, which is missing: ConstButNotRef


Nevertheless, currently there are two groups of types in FPC, simple types
like numerics for which const acts like passing by value,
and complex types for which const acts like passing by reference.
Note that currently const string *is passed by value*,
*except when the reference count equals to 1*, when it suddenly
behaves as if passed by reference.



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Wimpie Nortje

 Based on this promise, the compiler may decide to do some optimization.
 It will also warn you if it detects inside the code that you break
 your promise.
Based on my new knowledge of const strings I revisited the bug I
mentioned previously. I still have no idea where exactly I made the
error. And I never got a warning about the promise being broken.

For me the advantages of using const strings are completely dwarfed by
the time required to ensure I keep my side of the promise and still have
the risk that some small change in the future will break it without
causing compiler warnings.

 As soon as you understand this subtle difference, the problem disappears.
My suggestion is that the gist of the documentation be changed from Use
const strings, it is good for you to Const strings are powerful. They
are also dangerous. Don't use it unless you really really understand them
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread michael . vancanneyt



On Thu, 7 Jul 2011, Wimpie Nortje wrote:




Based on this promise, the compiler may decide to do some optimization.
It will also warn you if it detects inside the code that you break
your promise.

Based on my new knowledge of const strings I revisited the bug I
mentioned previously. I still have no idea where exactly I made the
error. And I never got a warning about the promise being broken.

For me the advantages of using const strings are completely dwarfed by
the time required to ensure I keep my side of the promise and still have
the risk that some small change in the future will break it without
causing compiler warnings.


Well, I program FPC and Delphi since many many years, in a multithreaded
server environment, and have never encountered a problem with this.

Given this, and the IMHO convoluted examples that were used to show the
'problem', I'm inclined to say that you must be writing some pretty 
strange code to have encountered this problem.


Given that Borland never decided to 'fix' it, I'm inclined to think that
they also don't consider it a real problem, but rather a corner case
(if they are aware of it at all).

That of course doesn't alter the fact that a corner case can seriously
bite you in the leg. I've had such cases as well. I just shrugged and
fixed my code.

C'est la vie.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 14:14, michael.vancann...@wisa.be wrote:

On Thu, 7 Jul 2011, Wimpie Nortje wrote:


For me the advantages of using const strings are completely dwarfed by
the time required to ensure I keep my side of the promise and still have
the risk that some small change in the future will break it without
causing compiler warnings.


Well, I program FPC and Delphi since many many years, in a multithreaded
server environment, and have never encountered a problem with this.

Given this, and the IMHO convoluted examples that were used to show the
'problem', I'm inclined to say that you must be writing some pretty 
strange code to have encountered this problem.


The original example ( a bug on mantis) had little strangeness. A global 
variable being modified in an OnChange handler of a TEdit.

This could very, very easily happen.


I think it is correct to say that there currently is a problem, and it 
starts in the documentation, and results in (many/most) people not knowing.
The extend of this not knowing (or at least not fully taking in 
account all consequences) is manifested in both the LCL and the FCL.


Both of them include code, that invites to break the promise. That is, 
it does not in itself break the promise. But I hides the promise made 
from the user, and therefore the user can break the promise without ever 
knowing it was made.
This happens when code provides events (such as many LCL Controls, or 
TStringList)
They accept strings (and there types) as const param to some methods, 
and then call back user code, in an event. This user code can modify the 
originally passed in variable.


Sure it could be said, that if I pass SomeValue to TStringList.Add, then 
I should see that I pass it as const param, and should know that I must 
not change it.

Only:
- These classes (TStringList, TControl) are provided to all users, 
including beginners. They contain no further warning.

- The user may not see the const declaration

And the user can not be sure, that he must follow the promise. 
TStringList could internally be protecting the value, and the user would 
not need to care about the promise.


In other words, the fact that such an expert option has been exposed in 
such manner to even beginners, implies that the authors themself had not 
fully reflected all consequences.

( At least in the LCL this has happened due to such unawareness)

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Thu, Jul 7, 2011 at 23:09, Martin f...@mfriebe.de wrote:
 I do think Florians, or Mattias  example are relevant.
 Let's for a moment ignore the const ansistring issue.

 The 2 examples prove, that even with const i : SomeRecord, your code can
 crash for none obvious reasons, IF you break the promise, not to modify the
 value of I, by modifying the value that you passed in.

Have I not just written, in the very detailed manner, that
reference counting is a technique specifically designed to prevent this problem?
That you code CAN NOT crash, much less for non-obvious reasons,
if you use ansistring?
That this is a critical advantage of using it, as compared to, say, shortstring?
That, finally, the examples with pointers and manual memory management
are proving just the opposite of what their author wanted -- i.e.
current implementation makes AnsiString no better than PChar in terms
of safety?

 That is:
  const x: sometype for any type (with the exception maybe of those , that
 are passed by value) can lead to undefined behaviour and/or crashes, if the
 promise of const is broken.

 If the above statement can be agreed on (and the examples show this), then
 why should the const ansi string be a bigger issue?

If you look at the point (2) of the mail you responded to,
you will see that I discuss this exact issue. Const string is passed by value,
and it does not lead to any undefined behaviour and crashes
except this case (barring, of course, as-yet-unknown compiler bugs).

 Yes, the const ansi string breaks the rules that ought to be provided by
 ref-counting.
 But it only breaks this ref-count promise, for code that is already unsave,
 even if ref-counting was in place.

How so? If the bug would be fixed, any procedure with const string parameter
will become perfectly safe, just as with, e.g.,  const integer.

 Given that the very same code would still be unsafe, even if ref counting
 was there, then why put ref-counting in there?
I am somewhat unsure what are you talking about here,
but if you mean the const string parameters, then
the statement above is incorrect.

 actually constref exists.
 but what you seem to want, which is missing: ConstButNotRef
Yes, but with less ugly syntax ;-)
Maybe constval?

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Mattias Gaertner
 
 

 michael.vancann...@wisa.be hat am 7. Juli 2011 um 13:10 geschrieben:

 [..]
  That's what I've been saying all along. You don't even need strings for it.
  Plain records and integers will do it just as well.
 Yes.
 I hope the example helps people understanding this.

 Maybe an example can be added to the documentation to explain that 'const' is
not a total protection.

 Mattias___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread michael . vancanneyt



On Thu, 7 Jul 2011, Mattias Gaertner wrote:


 
 

michael.vancann...@wisa.be hat am 7. Juli 2011 um 13:10 geschrieben:

[..]
 That's what I've been saying all along. You don't even need strings for it.
 Plain records and integers will do it just as well.
Yes.
I hope the example helps people understanding this.

Maybe an example can be added to the documentation to explain that 'const' is
not a total protection.


I had already planned it.

Michael.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 00:14,  michael.vancann...@wisa.be wrote:
 Given that Borland never decided to 'fix' it, I'm inclined to think that
 they also don't consider it a real problem, but rather a corner case
 (if they are aware of it at all).

Hm. My testing indicates that Delphi has this fixed since at least D2007.

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Hans-Peter Diettrich

Martin schrieb:

The original example ( a bug on mantis) had little strangeness. A global 
variable being modified in an OnChange handler of a TEdit.

This could very, very easily happen.


One of the reasons why *global variables* should be avoided.

DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 15:04, Alexander Klenin wrote:

On Thu, Jul 7, 2011 at 23:09, Martinf...@mfriebe.de  wrote:

I do think Florians, or Mattias  example are relevant.
Let's for a moment ignore the const ansistring issue.

The 2 examples prove, that even with const i : SomeRecord, your code can
crash for none obvious reasons, IF you break the promise, not to modify the
value of I, by modifying the value that you passed in.

Have I not just written, in the very detailed manner, that
reference counting is a technique specifically designed to prevent this problem?
That you code CAN NOT crash, much less for non-obvious reasons,
if you use ansistring?
That this is a critical advantage of using it, as compared to, say, shortstring?
That, finally, the examples with pointers and manual memory management
are proving just the opposite of what their author wanted -- i.e.
current implementation makes AnsiString no better than PChar in terms
of safety?


That is:
  const x: sometype for any type (with the exception maybe of those , that
are passed by value) can lead to undefined behaviour and/or crashes, if the
promise of const is broken.

If the above statement can be agreed on (and the examples show this), then
why should the const ansi string be a bigger issue?

If you look at the point (2) of the mail you responded to,
you will see that I discuss this exact issue. Const string is passed by value,
and it does not lead to any undefined behaviour and crashes
except this case (barring, of course, as-yet-unknown compiler bugs).


Yes, the const ansi string breaks the rules that ought to be provided by
ref-counting.
But it only breaks this ref-count promise, for code that is already unsave,
even if ref-counting was in place.

How so? If the bug would be fixed, any procedure with const string parameter
will become perfectly safe, just as with, e.g.,  const integer.
(code below written in my mailer, so my have typos, but should be enough 
to get the point


program Foo;
var Bar: ansistring;

procedure Test(const s: ansistring);
var x: TStringList;
begin
  if s[1] = '' then x := TStringList.Create;
  Bar := '';
  if s[1] = '' then x.Add('a'); // crash, because you changed Bar
end;

begin
  Bar := copy('afhdsgfyowahfol',2,4);
  Test(Bar);
end;

However the Example only demonstrates half the problem. The above *HACK* 
could be mad working. Within todays FPC it could even intentionally be 
used


EXCEPT:
The above hack is unsafe. It exploits undocumented behaviour. With any 
future FPC it's behaviour could totally change.
Any code that relies on an undocumented randomly found out detail about 
how the compiler *currentlly* translates some code, is very bad code: 
destined to crash some day.


Because if s is constant, then so is if s[1] = ''= so once this 
expression has been calculated, the compiler is free to keep the result 
cached. And that would change the flow of the above code.


Of course in the above example that would actually stop it from 
crashing, but in other code, it may start it crashing, or just return 
different results from what they used to be.


---
So in conclusion. Even if the above code did have ref counting, it would 
not work (code that changes it's behaviour at random due to compiler 
optimizations is not working).


Oh yes of course refcounting would do copy on write? well cast it to a 
pchar, to avoid the copy on write. It's an example, it's consrtructed to 
show the possibility of the issue in the minimum space, Hence it is not 
the most common world code. But it means it can happen in common world 
code.



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 16:14, Hans-Peter Diettrich wrote:

Martin schrieb:

The original example ( a bug on mantis) had little strangeness. A 
global variable being modified in an OnChange handler of a TEdit.

This could very, very easily happen.


One of the reasons why *global variables* should be avoided.

maybe it was a field on an object. Same problem
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread michael . vancanneyt



On Fri, 8 Jul 2011, Alexander Klenin wrote:


On Fri, Jul 8, 2011 at 00:14,  michael.vancann...@wisa.be wrote:

Given that Borland never decided to 'fix' it, I'm inclined to think that
they also don't consider it a real problem, but rather a corner case
(if they are aware of it at all).


Hm. My testing indicates that Delphi has this fixed since at least D2007.


No, it did not.

program tests;

{$APPTYPE CONSOLE}

uses
  SysUtils;

Var
  A : ansistring;

Procedure DoIt(Const B : ansistring);

begin
  A:='Something else';
  Writeln(B);
end;

begin
  A:='Something';
  DoIt(A);
  Readln;
end.

Writes 'Something', because the pointer B points to a block that has not
yet been invalidated. It works by accident.

Changing it to:

program tests;

{$APPTYPE CONSOLE}

uses
  SysUtils;

Var
  A : ansistring;

Procedure DoIt(Const B : ansistring);

begin
  A:='Something else';
  Writeln(B+' aha !!');
end;

begin
  A:='Something';
  DoIt(A);
  Readln; 
end.


The program crashes.

If you look at the generated assembler code, you'll see that no reference
count increasing is done in DoIt.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 01:48, Martin f...@mfriebe.de wrote:
 If you look at the point (2) of the mail you responded to,
 you will see that I discuss this exact issue. Const string is passed by
 value,
 and it does not lead to any undefined behaviour and crashes
 except this case (barring, of course, as-yet-unknown compiler bugs).

 (code below written in my mailer, so my have typos, but should be enough to
 get the point
[example skipped]

Above, I have quoted the relevant part of the mail you responded to.
If you read it, you will note that it discusses exactly the case
you tried to demonstrate.
Your example (after fixes identified below) proves my points, which
are, yet again:

1) That the code you posted would work quite correctly if const
string is fixed,
  including all the optimizations you are suggesting in the rest of
your message.
2) That it works correctly in (recent versions of) Delphi
3) That is will break in unpredictable fashion due to the bug we are
talking about.

Note: besides minor typos, you example does not cause error due to unrelated
issue: for some reason, string value returned from function has a refcount of 2
instead of 1.
I replaced call to Copy by 'x' + Bar + 'x' to ensure refcount of 1.

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 02:29,  michael.vancann...@wisa.be wrote:


 On Fri, 8 Jul 2011, Alexander Klenin wrote:

 On Fri, Jul 8, 2011 at 00:14,  michael.vancann...@wisa.be wrote:

 Given that Borland never decided to 'fix' it, I'm inclined to think that
 they also don't consider it a real problem, but rather a corner case
 (if they are aware of it at all).

 Hm. My testing indicates that Delphi has this fixed since at least D2007.

 No, it did not.

You are right, sorry. I have managed to bork my testing by inadverently
incrementing refcount.

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 16:27, Alexander Klenin wrote:


1) That the code you posted would work quite correctly if const
string is fixed,
   including all the optimizations you are suggesting in the rest of
your message.


No.

As I said: IF the result of constant expressions like s[a] = '' are 
cached (in future) depending on optimization level, then it breaks.


The 2nd evaluation, of this expression without optimization returns a 
different result from the 1st evaluation. (It may be that the example 
would need updating, but there is code where this can happen, including 
if ref-counting was done)


So depending on the 2nd evaluation being done, or cached (future 
optimization) the program flow differs.


Code which behaves unpredictable is broken.
In this case the none predictability comes from the fact that the code 
relies on a randomly observed and undocumented behaviour of todays fpc 
implementation. (the fact that today no such optimization is done)


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 02:35, Martin f...@mfriebe.de wrote:
 On 07/07/2011 16:27, Alexander Klenin wrote:

 1) That the code you posted would work quite correctly if const
 string is fixed,
   including all the optimizations you are suggesting in the rest of
 your message.

 No.

 As I said: IF the result of constant expressions like s[a] = '' are
 cached (in future) depending on optimization level, then it breaks.

Well, maybe you should run the code and see for youself --
I do not know how to explain this in even more detail.
It will *only* break due to the current optimization bug.
Remove the bug, and no breakage is possible,
with or without caching you describe.
Even now, if you ensure refcount1, no breakage is possible.

 The 2nd evaluation, of this expression without optimization returns a
 different result from the 1st evaluation. (It may be that the example would
 need updating, but there is code where this can happen, including if
 ref-counting was done)

 So depending on the 2nd evaluation being done, or cached (future
 optimization) the program flow differs.

It only differs now due to the current optimization bug.
Remove the bug, and the code will stop breaking.

 Code which behaves unpredictable is broken.
Exactly. This is the problem I hope to fix.

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 16:54, Alexander Klenin wrote:

On Fri, Jul 8, 2011 at 02:35, Martinf...@mfriebe.de  wrote:

On 07/07/2011 16:27, Alexander Klenin wrote:

1) That the code you posted would work quite correctly if const
string is fixed,
   including all the optimizations you are suggesting in the rest of
your message.

No.

As I said: IF the result of constant expressions like s[a] = '' are
cached (in future) depending on optimization level, then it breaks.

Well, maybe you should run the code and see for youself --
I do not know how to explain this in even more detail.
It will *only* break due to the current optimization bug.
Remove the bug, and no breakage is possible,
with or without caching you describe.
Even now, if you ensure refcount1, no breakage is possible.


The 2nd evaluation, of this expression without optimization returns a
different result from the 1st evaluation. (It may be that the example would
need updating, but there is code where this can happen, including if
ref-counting was done)

So depending on the 2nd evaluation being done, or cached (future
optimization) the program flow differs.

It only differs now due to the current optimization bug.
Remove the bug, and the code will stop breaking.


Ok, so here I go, an example without const = that means the refcount 
is increased.


Yet it crashes.
But the crash is NOT the issue. After all this crash is not caused by 
const. there is no const.

this crash is simply wrong code

But it shows something else.
It shows that even with refcount in place, it is possible to modify (via 
a global var) the content of a local string.


Yes, I use pointers, but it does not matter how I managed to change the 
content of s. All that matters is, that I broke the promise (assuming 
s was declared const)


But as soon as the content of s changes (and if s was declared const), 
the behaviour is simply unpredictable.


Because the second s[2] = 'x'  *could* be cached *or* evaluated; 
leading to a different execution path




---

program Project1; {$mode objfpc}{$H+}
uses Classes;

var Foo: String;

procedure Ouch(a: pchar);
begin
  a[0] := 'x';
end;

procedure Test1(  (*const*)  s: String);
var x: TStringList;
begin
  if s[2] = 'x' then
x := TStringList.Create;
  Ouch(@Foo[2]);
  if s[2] = 'x' then
x.Add('lets hope');
end;

begin
  Foo := 'ab'+'12';
  Test1(Foo);
  readln;
end.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 16:54, Alexander Klenin wrote:

On Fri, Jul 8, 2011 at 02:35, Martinf...@mfriebe.de  wrote:

On 07/07/2011 16:27, Alexander Klenin wrote:

1) That the code you posted would work quite correctly if const
string is fixed,
   including all the optimizations you are suggesting in the rest of
your message.




A different point about this.

What I understand you want is, for const s: string to do increase the 
ref-count. (regardless of any other issues there may or may not be).


But from today's point of view, from what cons string does today:
What is the point in doing this.?
Today this would be equal to simply remove the entire feature.

AFAIK, today all that cons string does is remove the ref count.

So basically you say, because of your reasoning, no one should be able 
to use such a feature in there code?



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 03:23, Martin f...@mfriebe.de wrote:

 Yes, I use pointers, but it does not matter how I managed to change the
 content of s. All that matters is, that I broke the promise (assuming s
 was declared const)

No, the whole point it is that it *does* matter.
Direct memory access lets you break anything --
class members' visibility, callstack frames,
built-in data structures like vtables, exceptions, refcounting, anything at all.
That does not mean all those features are useless and we should go back
to programming in assembler.
That also does not mean we should allow arbitrary breakage of those
features since you can break them anyway.

After all, you can break any string code the code much simpler:
(PInteger(s)-1)^:=-1;

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 03:35, Martin f...@mfriebe.de wrote:
 On 07/07/2011 16:27, Alexander Klenin wrote:

 1) That the code you posted would work quite correctly if const
 string is fixed,
   including all the optimizations you are suggesting in the rest of
 your message.


 A different point about this.

 What I understand you want is, for const s: string to do increase the
 ref-count. (regardless of any other issues there may or may not be).

 But from today's point of view, from what const string does today:
 What is the point in doing this.?
 Today this would be equal to simply remove the entire feature.

 AFAIK, today all that const string does is remove the ref count.

 So basically you say, because of your reasoning, no one should be able to
 use such a feature in there code?

It should do what is semantically natural for const -- namely,
prevent programmer from modifying the variable so declared.
Cf. const Integer.
I understand that const meaning in Object Pascal has long
since lost it's meaning, but still, what it should *not* do
is breaking user programs unexpectedly.
Just step away and think about the situation:
what would you think if, say, adding C++ const modifier
would convert working C++ program into subtly broken one?
Note that I am not against the optimization itself --
just against the optimization which changes the meaning of the code.
Imagine, again, if the optimizer would, say, pull repeated
calculation out of the loop without checking if the variables
may be changed by some procedure called from the loop body.
Also note that, implemented properly, removal of incref/decref calls
should not depend on any const declarations, it can be performed even
for non-const strings.

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Florian Klämpfl
 Also note that, implemented properly, removal of incref/decref calls
 should not depend on any const declarations, it can be performed even
 for non-const strings.
 

I'am awaiting your patch.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 03:49, Florian Klämpfl flor...@freepascal.org wrote:
 Also note that, implemented properly, removal of incref/decref calls
 should not depend on any const declarations, it can be performed even
 for non-const strings.


 I'am awaiting your patch.

So you agree with my design?

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 17:36, Alexander Klenin wrote:

On Fri, Jul 8, 2011 at 03:23, Martinf...@mfriebe.de  wrote:


Yes, I use pointers, but it does not matter how I managed to change the
content of s. All that matters is, that I broke the promise (assuming s
was declared const)

No, the whole point it is that it *does* matter.
Direct memory access lets you break anything --
class members' visibility, callstack frames,
built-in data structures like vtables, exceptions, refcounting, anything at all.
That does not mean all those features are useless and we should go back
to programming in assembler.
That also does not mean we should allow arbitrary breakage of those
features since you can break them anyway.

After all, you can break any string code the code much simpler:
(PInteger(s)-1)^:=-1;




ok, so  ansistring are the exception (or at least I will not search for 
further ways), because their copy-on-write adds an extra layer of 
protection.


but it still doesn't help.

Florian showed that the problem exist for ShortString.

In many cases the difference between ansi and short string s $H+/-.
Which means you move the breaking of your code into a compiler switch.

And also the example with the cached evaluation, would also apply to 
let's say records.


So in your scenario, the const param would then mean:
- const x: record = a promise not to modify the original record, or 
else you risk crashes and other errors

- const s: string = no promise, so you can do what you want

That doesn't make much sense either. Now const means different things 
depending on the type ?





___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Florian Klämpfl
Am 07.07.2011 18:55, schrieb Alexander Klenin:
 On Fri, Jul 8, 2011 at 03:49, Florian Klämpfl flor...@freepascal.org wrote:
 Also note that, implemented properly, removal of incref/decref calls
 should not depend on any const declarations, it can be performed even
 for non-const strings.


 I'am awaiting your patch.
 
 So you agree with my design?
 

About detecting if value parameters need no incr/decr. ref? I didn't see
any design yet.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 17:47, Alexander Klenin wrote:

On Fri, Jul 8, 2011 at 03:35, Martinf...@mfriebe.de  wrote:

AFAIK, today all that const string does is remove the ref count.

So basically you say, because of your reasoning, no one should be able to
use such a feature in there code?

It should do what is semantically natural for const -- namely,
prevent programmer from modifying the variable so declared.
Cf. const Integer.
I understand that const meaning in Object Pascal has long
since lost it's meaning, but still, what it should *not* do
is breaking user programs unexpectedly




Also note that, implemented properly, removal of incref/decref calls
should not depend on any const declarations, it can be performed even
for non-const strings.


Differnet feature. Nice to have...

But no compiler can identify every occurrence where the ref count can be 
ommitted.


so it still stands:
What you want, is the removal of a feature from pascal. The feature for 
the programmer to explicitly skip the ref count (at the programmers own 
risk)


If that is the case: Should we remove move / fillchar too? Because 
they can do the same.


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 03:55, Martin f...@mfriebe.de wrote:
 That doesn't make much sense either. Now const means different things
 depending on the type ?

It already does. I agree it makes no sense, but this is much larger problem,
which deserves at least a separate discussion thread.

Currently, there are four meaninigs of const:
1) Const by value -- like Integer
2) Const by reference -- like shortstring
3) Const by reference, but not really const -- like objects
4) Const by value, excapt rare breakage -- AnsiString
  (and interfaces, but let's not touch that can of worms in this thread :-) )

I propose to remove meaning (4).

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Florian Klämpfl
Am 07.07.2011 19:00, schrieb Alexander Klenin:
 On Fri, Jul 8, 2011 at 03:55, Martin f...@mfriebe.de wrote:
 That doesn't make much sense either. Now const means different things
 depending on the type ?
 
 It already does. I agree it makes no sense, but this is much larger problem,
 which deserves at least a separate discussion thread.
 
 Currently, there are four meaninigs of const:
 1) Const by value -- like Integer
 2) Const by reference -- like shortstring
 3) Const by reference, but not really const -- like objects
 4) Const by value, excapt rare breakage -- AnsiString
   (and interfaces, but let's not touch that can of worms in this thread :-) )
 
 I propose to remove meaning (4).
 

Unlogical. 2) and 4) are coupled.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 03:57, Florian Klämpfl flor...@freepascal.org wrote:
 I'am awaiting your patch.

 So you agree with my design?


 About detecting if value parameters need no incr/decr. ref? I didn't see
 any design yet.

See http://bugs.freepascal.org/view.php?id=19605 and this thread


-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 04:06, Florian Klämpfl flor...@freepascal.org wrote:
 Am 07.07.2011 19:00, schrieb Alexander Klenin:
 Currently, there are four meaninigs of const:
 1) Const by value -- like Integer
 2) Const by reference -- like shortstring
 3) Const by reference, but not really const -- like objects
 4) Const by value, excapt rare breakage -- AnsiString
   (and interfaces, but let's not touch that can of worms in this thread :-) )

 I propose to remove meaning (4).


 Unlogical. 2) and 4) are coupled.

This whole construct is unlogical. Logically, const a should mean
just assignment to a is a compile-time error.
But this is not achievable due to compatibility reasons.
Still, I suggest that (4) is a (small, but still) evil, and sould be removed.

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 18:09, Alexander Klenin wrote:


About detecting if value parameters need no incr/decr. ref? I didn't see
any design yet.

See http://bugs.freepascal.org/view.php?id=19605 and this thread

that is about at runtime, in debug compiled exe

We are talking about compile time decissions


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 04:16, Martin f...@mfriebe.de wrote:
 On 07/07/2011 18:09, Alexander Klenin wrote:

 About detecting if value parameters need no incr/decr. ref? I didn't see
 any design yet.

 See http://bugs.freepascal.org/view.php?id=19605 and this thread

 that is about at runtime, in debug compiled exe

 We are talking about compile time decissions

Well, filter out all notes except mine then ;-)

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Florian Klämpfl
Am 07.07.2011 19:14, schrieb Alexander Klenin:
 On Fri, Jul 8, 2011 at 04:06, Florian Klämpfl flor...@freepascal.org wrote:
 Am 07.07.2011 19:00, schrieb Alexander Klenin:
 Currently, there are four meaninigs of const:
 1) Const by value -- like Integer
 2) Const by reference -- like shortstring
 3) Const by reference, but not really const -- like objects
 4) Const by value, excapt rare breakage -- AnsiString
   (and interfaces, but let's not touch that can of worms in this thread :-) 
 )

 I propose to remove meaning (4).


 Unlogical. 2) and 4) are coupled.
 
 This whole construct is unlogical. Logically, const a should mean
 just assignment to a is a compile-time error.
 But this is not achievable due to compatibility reasons.
 Still, I suggest that (4) is a (small, but still) evil, and sould be removed.

Why? 2) is exactly the same? The const contract with the compiler is broken.

Besides this, people like Martin Schreiber won't be happy if a procedure
suddently eats hundreds of extra clock cycles for nothing.


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 03:58, Martin f...@mfriebe.de wrote:
 On 07/07/2011 17:47, Alexander Klenin wrote:
 Also note that, implemented properly, removal of incref/decref calls
 should not depend on any const declarations, it can be performed even
 for non-const strings.

 Differnet feature. Nice to have...

Agreed.

 But no compiler can identify every occurrence where the ref count can be
 ommitted.

 so it still stands:
 What you want, is the removal of a feature from pascal. The feature for the
 programmer to explicitly skip the ref count (at the programmers own risk)

Well, don't you think that expliciitly ask to skip refcount feature
is quite different from constant parameter?
At some stage, semantic annotation got conflated with a specific
optimization it allowed.
I propose to decouple them -- let the const mean constant
(which, by the way, can not be achieved currently, so it would be new feature),
and do refcount skipping only if safe
(or, for the really critical codepaths, introduce a separate,
explicitly-named annotation,
something like const norefcount).

 If that is the case: Should we remove move / fillchar too? Because they
 can do the same.
There is Move and there is assignment.
You would not advocate always perform Move on assignment,
beause it is slightly faster, even if it breaks some code like
AnsiString assignment?

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 04:22, Florian Klämpfl flor...@freepascal.org wrote:

 Why? 2) is exactly the same? The const contract with the compiler is broken.

Since when are passing by value and by reference the same?

 Besides this, people like Martin Schreiber won't be happy if a procedure
 suddently eats hundreds of extra clock cycles for nothing.
For those people, I proposed to add optimization switch to the UNCERTAIN
group. I just do not think it should be on by default.
Also, can you Cc him -- maybe we should ask him directly?

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Alexander Klenin
On Fri, Jul 8, 2011 at 04:52, Martin f...@mfriebe.de wrote:
 if const reads: I (the programmer) tell the compiler this value is going to
 be constant
 versus: I ask the compiler to help me avoid changing it
 But as in my other mail, it may not be best named (but now we are changing
 topic, it's not about the feature anymore, it's about the name)

Well, that difference is a bit on the of philosophic side in general case,
and, as I said, totally changing the meaning of const is not what
I argue for in this thread. (IMHO const should mean both).
But, in the specific case of const string parameters in FPC,
the problem is that it *already* means both,
and I suspect a lot of code depends on the current meaning.
So this specific case, while maintaining the
contract of no refcounting on const runs contrary to the (IMO)
much more meaningful contacts like adding const increases safety of the code
and no memory errors from using ansistrings without messing with pointers.

 But at 2nd sight, I retuned to the example with the caching of expresion
 results.. And If the feature would really mean const the value of this
 variable will not change, not from within nor from outside this function
 (and that is what in case of a record (passed by ref) is needed to be real
 const, and allow all the optimization.
I do not quite understand this passage, but did you note that
currently the caching you propose would be unsafe for strings,
but you can make it safe if you fix this bug?
That is, my proposal increases the possibilities for optimization.

 in c++ you can mark an entire method to be const. Means that method can not
 call any thing, that modifies the object.
 If I wanted to go all the way in pascal, then const x: type should mean:
 - the compiler allows no modification of x in the procedure (exists in fpc)
 - the compiler allows x only as param, if the param is const too (exists in
 fpc)
 - (new) the compiler prevents calling any other code (any method, procedure,
 or event) unless it has proven knowlege that this code does not do anything
 that could modify the value of x
  eg only calls to methods that do not modify any variable of the type of x
 at all (and that do not call anything that does...)
Note the distinction here: compiler must only refuse code it knows to
be incorrect,
but must only make optimizations it knows to be correct.
So the right answer for two latter cases is to allow them,
but disable optimizations -- which is exactly what I proposed in the
first place.

 Neither do I advocate  to use const, unless you know what you do. And if
 anyone advocates it, then it's a problem (but not a problem of the feature)
Just google const string parameter Delphi to see the advocating.


-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread Martin

On 07/07/2011 19:12, Alexander Klenin wrote:



Neither do I advocate  to use const, unless you know what you do. And if
anyone advocates it, then it's a problem (but not a problem of the feature)

Just google const string parameter Delphi to see the advocating.



That's a different issue.

I have stated several times that to me const param is  similar like 
fillchar(StringArray[0], x, 0)


for both you need to be aware of certain details abstracted from the 
average use.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-07 Thread reynolight
Am 07.07.2011 19:54, schrieb Alexander Klenin:
 ...
 The problem with this particular feature is that *nobody* seems to use
 it correctly --
 if even compiler developers did not get it right, what can we expect
 from ordinary
 users?

Here I am. Probably the most ordinary FP user on the planet. Just let me
throw in this discussion, to be honest, for years, I do not have any
issues with const parameters, related to this debate. The contract is
completely ok for me. And I always understood it as my promise to the
compiler, as Michael pointed out. Not at all reversely, as the
compiler's commitment.

So I am perfectly happy with this promise. Except, sometimes, when an
related error is thrown, I have to remember again, that const
automatically excludes dynamic function or operation results as a
parameter, as well.

From my personal point of view, THIS has nothing to do with the promise,
not to modify a parameter, declared as const, during the called
routine is running. But I cannot imagine that there is any chance for a
change, since it's probably always done like this, in each and every
version of the compiler.

Reyno.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-06 Thread Chad Berchek
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, 

Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Alexander Klenin
On Tue, Jul 5, 2011 at 14:02, Chad Berchek ad...@vobarian.com wrote:
 We also have to remember that *probably almost nobody* remembers fixing a bug 
 related to this.
 That's because most people who come up against this bug probably have no clue 
 what is happening and only by making some other changes do they 
 coincidentally fix it.
 I propose that for a problem like this you cannot rely on reported incidents 
 to determine how frequent it is.

Yesterday I have initiated a review of the (Delphi) code in one
company I work for, to check for
this issue. So far, we have found two instances of procedures with
non-const string parameters
with the comment to the effect of do not change to const, or the code
will break.
One of these instances is fairly recent, and the developer who made
the change did remember
that it cost him more than a work-day to fix -- and that was after the
crash report from the client.
The company is now considering outright ban on all const string parameters,
similar to already implemented ban in const interface parameters.

I really think FPC should do better than this.
See also:
http://stackoverflow.com/questions/5851584/are-const-string-parameters-thread-safe
http://chrisbensen.blogspot.com/2007/11/string-parameters-in-delphi.html?showComment=119637324#c7340129019635270394

Repeating my proposal from the bug-report
(http://bugs.freepascal.org/view.php?id=19605):
1) Introduce new optimization switch, e.g.  {$OPTIMIZATION CONSTNOREF},
preferably locally-scoped.
2) Include that switch in UNCERTAIN group and disable it by default
3) In certain specific cases, enable the optimization anyway if
it can be proved safe.
4) Enable this optimization *even for non-const parameters* in the same cases.

I hope the last two points can seriously reduce performance hit
(or even gain some improvements) without compromising correctness.
From the top of my head, I can see following safe cases available
without cross-function analysis:
1) inlined procedures
2) leaf procedures
3) procedures where string parameters are not accessed after the first
call to another function

The last case, while sounding artificial, can be actually quite common
in the setters
for string properties:

procedure TMyObj.SetProp(AValue: String);
begin
  if FProp = AValue then exit;
  FProp := AValue;
  MyObjChanged;
end;

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Martin

On 05/07/2011 04:02, Chad Berchek wrote:


Martin wrote:

I don't think it is a bug.

...

(const s: string) is a declaration by the programmer, that the
variable (the string) will not be modified at all. That is neither by
the procedure called, nor by any code outside the procedure, via any
other  reference to the data. If the programmer sticks to what he
declared, then it works, if not it crashes.


Is that true? I am not necessarily asserting that your statement is 
false; it could well be true. However I personally have not seen it 
documented so if anyone has a reference I would like to see it. As far 
as I have been able to tell from the docs of Delphi and FPC, the const 
declaration does NOT mean the programmer promises to not modify the 
instance; it means he promises to not modify the variable, which the 
compiler does indeed enforce.


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)




Anyway, if you do not like the feature do not use it.


Unfortunately, that is not true. I don't have to use const in my own 
code, but I cannot control the fact that it is already widely used in 
other libraries, including those of FPC.


Well yes. But that is not a problem limited to the const string param. 
Any code you use in your app, can contain any kind of bug.


I just want to ask, after looking at the demo, is this not the least 
bit scary to anyone? I mean, you can make one very simple, tiny change 
and turn a perfectly working program into an immediate crash for no 
apparent reason. The secrets are buried in there. In a real world 
scenario you wouldn't be able to see it crash so easily. It may or may 
not crash, or it may just crash much later, or it may not crash but 
just be a security vulnerability waiting for someone to discover.
Very true, in fact the whole issue has only recently been discovered in 
the LCL too (as a bug in the LCL)


We also have to remember that *probably almost nobody* remembers 
fixing a bug related to this. That's because most people who come up 
against this bug probably have no clue what is happening and only by 
making some other changes do they coincidentally fix it. I propose 
that for a problem like this you cannot rely on reported incidents to 
determine how frequent it is.


I would gop as far as to say, every time someone use a const string 
param without knowing the real meaning,  the resulting code should be 
considder buggy. Even if it works by accident. Wrongly written code, 
that works by accident, to me is close enough to being a bug.


Looking at it like this, it is probably correct to say, that this 
feature has cause a lot of bugs already.


But it doesn't mean the feature itself is buggy. It maybe that it isn't 
documented well enough, as to few people are aware of it. It may even be 
that the indrotuction of this feature was not a good idea, or should at 
least have been done in a way that would make the risks more obvious.

Of course should have done is past, little point in discussing that now.

BTW, there are similar pitfalls with functions like fillchar, or move

x: array of string;
fillbyte(x[0], (length(x)-1)*sizeof(string), 0)

If there are any strings with content in the array, it will leak
using move() on an array like this will lead to crashes later in the 
code...


Only difference, for those functions more (not all) people know of the 
dangers...



This is one of the reasons, why I have asked for a range-ceck like 
feature for such const params (http://bugs.freepascal.org/view.php?id=19605)

- Not only would it help finding where the problem occurs
- It would also help creating awareness:
  Many people tend to switch on all the check options (range, overflow, 
io, stack...) during development. So would they do for a check detecting 
const param issues.
  The hope is that simple by noting the features, some would look up 
it's documentations. The others would do so, once the check raises an alert.



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread michael . vancanneyt



On Tue, 5 Jul 2011, Martin wrote:


On 05/07/2011 04:02, Chad Berchek wrote:


Martin wrote:

I don't think it is a bug.

...

(const s: string) is a declaration by the programmer, that the
variable (the string) will not be modified at all. That is neither by
the procedure called, nor by any code outside the procedure, via any
other  reference to the data. If the programmer sticks to what he
declared, then it works, if not it crashes.


Is that true? I am not necessarily asserting that your statement is false; 
it could well be true. However I personally have not seen it documented so 
if anyone has a reference I would like to see it. As far as I have been 
able to tell from the docs of Delphi and FPC, the const declaration does 
NOT mean the programmer promises to not modify the instance; it means he 
promises to not modify the variable, which the compiler does indeed 
enforce.


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)


There is no bug.

You can always fool the compiler. The compiler trusts you and assumes that
what you tell her is true, namely, that the called code will not modify the
const parameter (in the case of an ansistring: a pointer). That's it. 
Based on this she may or may not perform some optimizations.


For what it's worth, you can recreate the alleged problem just as easily in
C or with non-reference-counted classes.

For example:

uses sysutils,classes;

Var
  C : TComponent;

Procedure DoSomething(Const AC : TComponent);

begin
  FreeAndNil(C);
  AC.Name:=AC.Name+'_component'; // You can skip this, even.
  Writeln(AC.Name);
end;

begin
  C:=TComponent.Create(nil);
  C.Name:='Something';
  DoSOmething(C);
end.

Will not produce the desired effect. The compiler cannot warn you against
this.

I understand that with Ansistrings it's slightly more convoluted than this,
but it's the same principle.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Felipe Monteiro de Carvalho
Maybe the compiler should start issuing hints or warnings for all
places where one uses const with ansistring, so that people who don't
care about the speed advantage can start removing those const
ansistrings from their code base.

-- 
Felipe Monteiro de Carvalho
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Thaddy

On 5-7-2011 12:34, Felipe Monteiro de Carvalho wrote:

Maybe the compiler should start issuing hints or warnings for all
places where one uses const with ansistring, so that people who don't
care about the speed advantage can start removing those const
ansistrings from their code base.

Yes, but is is no bug! 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.
That is also part of the speed optimization: the compiler doesn't have 
to check because of this contract. This is also the case in many other 
languages.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Hans-Peter Diettrich

michael.vancann...@wisa.be schrieb:


On Tue, 5 Jul 2011, Martin wrote:


On 05/07/2011 04:02, Chad Berchek wrote:


Martin wrote:

I don't think it is a bug.

...

(const s: string) is a declaration by the programmer, that the
variable (the string) will not be modified at all. That is neither by
the procedure called, nor by any code outside the procedure, via any
other  reference to the data. If the programmer sticks to what he
declared, then it works, if not it crashes.


Is that true? I am not necessarily asserting that your statement is 
false; it could well be true. However I personally have not seen it 
documented so if anyone has a reference I would like to see it. As 
far as I have been able to tell from the docs of Delphi and FPC, the 
const declaration does NOT mean the programmer promises to not modify 
the instance; it means he promises to not modify the variable, which 
the compiler does indeed enforce.


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)


There is no bug.

You can always fool the compiler. The compiler trusts you and assumes that
what you tell her is true, namely, that the called code will not modify the
const parameter (in the case of an ansistring: a pointer). That's it. 
Based on this she may or may not perform some optimizations.


That's my opinion as well :-)

All the rumor about hard to find errors IMO is due to the users, which 
simply should avoid const when their overall code then may break itself.


I'd second that const with object references is a bug, and should be 
removed from all library code (RTL, FCL, LCL...). But this is only a 
matter of style, not affecting compilation in any way.



[examples snipped]

Will not produce the desired effect. The compiler cannot warn you against
this.

I understand that with Ansistrings it's slightly more convoluted than this,
but it's the same principle.


People with according bugs in their code should be happy with an added 
compiler option, that disables const parameter optimization. That's a 
quick workaround for urgent fixes, where otherwise an in-depth analysis 
of the entire application were required.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Martin

On 05/07/2011 11:24, michael.vancann...@wisa.be wrote:



On Tue, 5 Jul 2011, Martin wrote:


On 05/07/2011 04:02, Chad Berchek wrote:


Martin wrote:

I don't think it is a bug.

...

(const s: string) is a declaration by the programmer, that the
variable (the string) will not be modified at all. That is neither by
the procedure called, nor by any code outside the procedure, via any
other  reference to the data. If the programmer sticks to what he
declared, then it works, if not it crashes.


Is that true? I am not necessarily asserting that your statement is 
false; it could well be true. However I personally have not seen it 
documented so if anyone has a reference I would like to see it. As 
far as I have been able to tell from the docs of Delphi and FPC, the 
const declaration does NOT mean the programmer promises to not 
modify the instance; it means he promises to not modify the 
variable, which the compiler does indeed enforce.


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)


There is no bug.


I think you misunderstood me.  There is a (or there may be) a bug.  But 
*not* in the compiler, and *not* in the implementation of const string.
I explicitly pointet that out on the top of the quotation I don't think 
it is a bug. (with reference to the feature itself)


The bug(s) is/are in user code, where the const construct is 
*incorrectly* used.


An I was merely pointing out, that any usage without knowledge what it 
does is incorrect usage (even if by accident it works). Therefore one 
might consider such unaware/unknowing usage as a bug (a bug in the users 
code)


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Felipe Monteiro de Carvalho
On Tue, Jul 5, 2011 at 1:04 PM, Thaddy tha...@thaddy.com wrote:
 On 5-7-2011 12:34, Felipe Monteiro de Carvalho wrote:

 Maybe the compiler should start issuing hints or warnings for all
 places where one uses const with ansistring, so that people who don't
 care about the speed advantage can start removing those const
 ansistrings from their code base.

 Yes, but is is no bug!

ppcontroller.pas(40,31) Hint: Parameter AStartDate not used

That's also not a bug, but nevertheless the compiler issued a Hint for it.

-- 
Felipe Monteiro de Carvalho
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Hans-Peter Diettrich

Thaddy schrieb:

That is also part of the speed optimization: the compiler doesn't have 
to check because of this contract.


More important: the compiler can omit try-finally sections, otherwise 
required for safe refcounting of non-const strings.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread cobines
2011/7/5  michael.vancann...@wisa.be:
 You can always fool the compiler. The compiler trusts you and assumes that
 what you tell her is true, namely, that the called code will not modify the
 const parameter (in the case of an ansistring: a pointer). That's it. Based
 on this she may or may not perform some optimizations.

In case of ansistrings, inside the procedure you cannot also finalize
the instance that the const parameter points to. But you can modify
that instance through other variables. For example :

procedure mclass.dot(const s: string);

Here you know that you cannot modify 's'. But you may not know that
you cannot also change mclass.ftext variable, which actually 's'
points to because apparently someone called
mclass.dot(mclass.fsometext).

Maybe it is programmer error and it should be said: never call
mclass.dot with mclass.ftext as a parameter because it may crash.
Maybe the const should have never been there in the first place. I
would say if procedure writes to some non-local strings, never add
'const' to parameter.

It is easy to start adding 'const' to every parameter but some may not
be aware of the dangers it may later bring. It should be a well
thought decision.

--
cobines
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Florian Klaempfl
Am 04.07.2011 22:39, schrieb Chad Berchek:
 I've been reading over some of the recent discussion about reference
 counting problems with const string parameters. I've done some
 experiments and I believe that the so-called const optimization is a
 serious flaw, not just a corner case of questionable legitimacy. I have
 some sample code I will show which should be quite scary. Additionally,
 this is a security vulnerability. It is also a quiet bug, because it may
 go undetected for a long time but randomly result in unreproducible
 crashes.
 
 Consider:
 * It does not affect just global variables but also object fields. While
 global variables are used rarely, object fields are used constantly in OOP.
 * It does not affect just strings but also interfaces and dynamic arrays.

It affects more types, even shortstring suffers from it, the program
does not crash but might behave not as expected (similiar examples can
be created for normal arrays or records as well):

var
  s : shortstring;

procedure p(const s1 : shortstring);
  begin
s:='Ops';
writeln(s1);
  end;

begin
  s:='Hello world';
  p(s);
end.

I see it only as a either or all or none: either the const optimization
is done for no types or for all types where it's useful. Everything else
is even more dangerous (if you consider this behaviour as dangerous)
because the outcome is unpredictible. However, I doubt that people will
be happy, if huge data arrays, records or shortstrings are always copied
and no const optimization is carried out.

As written in some of the bug reports, I consider as a better solution:
- Pointer checking of constant parameters of types like ansistrings,
interfaces at procedure exit. Together with heaptrc and keep_released
enabled, this catches all cases of disposed const parameters and
probably a lot more pointer errors.
- Like the scrambling of local parameters with -gttt, some checksumming
for contant parameters could be implemented. This catches not only the
modified constant parameter but also aliasing problems.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Martin

On 05/07/2011 16:28, Florian Klaempfl wrote:

As written in some of the bug reports, I consider as a better solution:
- Pointer checking of constant parameters of types like ansistrings,
interfaces at procedure exit. Together with heaptrc and keep_released
enabled, this catches all cases of disposed const parameters and
probably a lot more pointer errors.
- Like the scrambling of local parameters with -gttt, some checksumming
for contant parameters could be implemented. This catches not only the
modified constant parameter but also aliasing problems.


There would be the possibility to extend heaptrc mem manager.
Every mem block gets a release-lock- or const-counter (and maybe a 
checksum field).


then any memory used in a const param, can be protected (via the mem 
manager) against release (ONLY if compiled with sanity check).


That would catch the releases due to refcount going to 0, were it must 
not be allowed.


The checksum can be used for general checking.

The checksum should be toggle-able by a 2nd switch (and maybe with a 
configurable upper limit for mem size, so to skip tests for very large data)



Variables on the stack, do not get the mem-alloc protection = but they 
can not be released early anyway

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Alexander Klenin
On Tue, Jul 5, 2011 at 22:51, Martin f...@mfriebe.de wrote:
 I think you misunderstood me.  There is a (or there may be) a bug.  But
 *not* in the compiler, and *not* in the implementation of const string.
 I explicitly pointet that out on the top of the quotation I don't think it
 is a bug. (with reference to the feature itself)

 The bug(s) is/are in user code, where the const construct is *incorrectly*
 used.

Well, then the following changes are in order:
1) The documentation should recommend users to never use const
string parameters
except cases where they can prove it to be safe.
Moreover, since the safety of such code may be compromised by
completely unrelated changes
(e.g. by adding {$INLINE OFF} for debugging purposes),
const modifier should not be used at all except the most
performance-critical code.
This is quite the opposite of the current practice, where all string
parameters are usually
marked by const.
2) All such incorrect usage should be removed from LCL and FCL
(for example: event handlers in LCL and TStrings methods in FCL).

Personally, I think this solution is inferior to my proposal of
implementing the optimization
correctly by default.

 An I was merely pointing out, that any usage without knowledge what it does
 is incorrect usage (even if by accident it works). Therefore one might
 consider such unaware/unknowing usage as a bug (a bug in the users code)

Ok, FPC and Lazarus teams now have many bugs to fix ;-)
I''ll start reviewing my TAChart code in a few days.

-- 
Alexander S. Klenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Hans-Peter Diettrich

cobines schrieb:


procedure mclass.dot(const s: string);

Here you know that you cannot modify 's'. But you may not know that
you cannot also change mclass.ftext variable, which actually 's'
points to because apparently someone called
mclass.dot(mclass.fsometext).


You *can* change mclass.ftext, but this can cause *trouble*.


Maybe it is programmer error and it should be said: never call
mclass.dot with mclass.ftext as a parameter because it may crash.
Maybe the const should have never been there in the first place. I
would say if procedure writes to some non-local strings, never add
'const' to parameter.


Good advice :-)

DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Alexander Klenin
On Wed, Jul 6, 2011 at 02:41, Martin f...@mfriebe.de wrote:
 On 05/07/2011 16:28, Florian Klaempfl wrote:

 As written in some of the bug reports, I consider as a better solution:
 - Pointer checking of constant parameters of types like ansistrings,
 interfaces at procedure exit. Together with heaptrc and keep_released
 enabled, this catches all cases of disposed const parameters and
 probably a lot more pointer errors.
 - Like the scrambling of local parameters with -gttt, some checksumming
 for contant parameters could be implemented. This catches not only the
 modified constant parameter but also aliasing problems.

 There would be the possibility to extend heaptrc mem manager.
 Every mem block gets a release-lock- or const-counter (and maybe a
 checksum field).

 then any memory used in a const param, can be protected (via the mem
 manager) against release (ONLY if compiled with sanity check).

 That would catch the releases due to refcount going to 0, were it must not
 be allowed.

 The checksum can be used for general checking.

 The checksum should be toggle-able by a 2nd switch (and maybe with a
 configurable upper limit for mem size, so to skip tests for very large data)


This seems complicated to me. How about a simple memory poisoning?
For example, with the attached patch the code trying to access const
string parameter which has been already destroyed is likely to fail
spectacularly instead of maybe working depending on memory layout.

-- 
Alexander S. Klenin


heaptrc_poisoning.patch
Description: Binary data
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Jonas Maebe

On 05 Jul 2011, at 18:27, Alexander Klenin wrote:

 2) All such incorrect usage should be removed from LCL and FCL
 (for example: event handlers in LCL and TStrings methods in FCL).

Changing TStrings like that would break the compilation of any code that 
overrides its methods (since they also have to repeat/leave out const).

 Personally, I think this solution is inferior to my proposal of
 implementing the optimization
 correctly by default.

Your suggestions about the safe cases were wrong, as far as I can tell. As 
soon as a field, global variable or variable from a parent function (in case of 
nested functions) is changed, the parameter may also change if it is declared 
as const (because the field/(global) variable may contain the value that was 
passed in as const parameter). Any pointer may also alias them.

Since the behaviour of const for automated types is explicitly defined by 
Borland as not causing any changes in reference counting (see the note at the 
bottom of http://docwiki.embarcadero.com/RADStudio/en/Using_Reference_Counting 
), I think Martin/Florian's proposal to add the ability for adding extra 
compiler checks is best. It's similar to how range and overflow checking are 
optional.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread Michael Van Canneyt



On Tue, 5 Jul 2011, Jonas Maebe wrote:



On 05 Jul 2011, at 18:27, Alexander Klenin wrote:


2) All such incorrect usage should be removed from LCL and FCL
(for example: event handlers in LCL and TStrings methods in FCL).


Changing TStrings like that would break the compilation of any code that 
overrides its methods (since they also have to repeat/leave out const).


Personally, I think this solution is inferior to my proposal of
implementing the optimization
correctly by default.


Your suggestions about the safe cases were wrong, as far as I can tell.
As soon as a field, global variable or variable from a parent function (in
case of nested functions) is changed, the parameter may also change if it
is declared as const (because the field/(global) variable may contain the
value that was passed in as const parameter).  Any pointer may also
alias them.

Since the behaviour of const for automated types is explicitly defined
by Borland as not causing any changes in reference counting (see the note
at the bottom of
http://docwiki.embarcadero.com/RADStudio/en/Using_Reference_Counting ), I
think Martin/Florian's proposal to add the ability for adding extra
compiler checks is best.  It's similar to how range and overflow checking
are optional.


I agree with this proposal.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re[2]: [fpc-devel] Const optimization is a serious bug

2011-07-05 Thread José Mejuto
Hello FPC,

Tuesday, July 5, 2011, 6:44:24 PM, you wrote:

JM Since the behaviour of const for automated types is
JM explicitly defined by Borland as not causing any changes in
JM reference counting (see the note at the bottom of
JM http://docwiki.embarcadero.com/RADStudio/en/Using_Reference_Counting
JM ), I think Martin/Florian's proposal to add the ability for adding
JM extra compiler checks is best. It's similar to how range and
JM overflow checking are optional.

But adding a checksum over allocated data or only over control data ?

This changes should be detected ?

var
  a: ansistring;
  
procedure DoSomehting(const v: ansistring);
begin
  a[1]:='a';
end;

begin
  a:='b';
  DoSomething(a);
end.

Maybe simply add a constRefCount field which is only used with the
check automagic types turned on ? Anyway the worst behaviour is
refcount related do not ? If refcount should be updated and the
variable have a constRefCount0 then something went wrong. Also this
mode should not impose a serious performance penalty.

-- 
Best regards,
 José

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


  1   2   >