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


[fpc-devel] MySQL 5.1 and Double (trouble)

2011-07-10 Thread Andrew Brunner
Can someone check the status of update if the bind parameter for
double decimal values?

I'm getting unexpected rounding errors after updating - the data in
the column looks different than what was specified during the update
statement.

Value: double;
Query.Params.ParamByName(sName).AsFloat:=Value;

1.) Update Value  : 40734.825668912039
2.) Actual Value after update : 40734.825668912
3.) Actual Value on read   : 40734.825668912003

As far as I know this is a relatively new problem.  Could be with
Ubuntu but was someone doing MYSQL work lately?
___
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