Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2010-10

Types.IntersectRect(), probably bug or misusage VERY URGENT

17 messages · 8 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

zeljko
Hi all,
Someone reported bug in gtk2lcl which crashes lazarus ide. I've found that
intersectRect usage from types (from r 27870) makes that.
So imagine next code:
var
  R, SrcRect: TRect;
begin
   R := Rect(0, 0, 22, 22);
   SrcRect := Rect(0, 0, 24, 24);
   Types.IntersectRect(R, SrcRect, R);
end;
In this case RETURNED value from intersectRect will be wrong R = 0, 0, 24, 24.
Now the question is: first param of Intersect is var, others are consts.
function IntersectRect(var Rect : TRect;const R1,R2 : TRect) : Boolean;
begin
  Rect:=R1; // <--------- WHAT IF Rect = R2 as in my example above ?
  with R2 do
    begin
    if Left>R1.Left then
      Rect.Left:=Left;
    if Top>R1.Top then
      Rect.Top:=Top;
    if Right<R1.Right then
      Rect.Right:=Right;
    if Bottom<R1.Bottom then
      Rect.Bottom:=Bottom;
    end;
  if IsRectEmpty(Rect) then
    begin
    FillChar(Rect,SizeOf(Rect),0);
    IntersectRect:=false;
    end
  else
    IntersectRect:=true;
end;

So MAIN question is:
1.My example shows misusage of IntersectRect
2.FPC Types.IntersectRect() have bug

thanks,
zeljko

Reply by email

zeljko
to Felipe Monteiro de Carvalho: I guess it depends on how you see it. Anyway, the solution would be trivial, just store…
Felipe Monteiro de Carvalho wrote 8 lines
On Tue, Oct 26, 2010 at 3:14 PM, zeljko wrote: > No, I've opened an issue and Jonas closed with good explanation - we had > misusage of IntersectRect in gtk/gtk2 interfaces (I've fixed both) ... so > not bug. I guess it depends on how you see it. Anyway, the solution would be trivial, just store the inputs in local vars.

I know, but generally speaking Jonas is correct, but you too :). I don't like current fpc solution too, but can live with it.

zeljko

Reply by email

Sergei Gorelkin
to zeljko

zeljko пишет:

Show quoted text 12 lines
On Tuesday 26 October 2010 15:13, Felipe Monteiro de Carvalho wrote: > On Tue, Oct 26, 2010 at 3:14 PM, zeljko wrote: >> No, I've opened an issue and Jonas closed with good explanation - we had >> misusage of IntersectRect in gtk/gtk2 interfaces (I've fixed both) ... so >> not bug. > I guess it depends on how you see it. > > Anyway, the solution would be trivial, just store the inputs in local vars. I know, but generally speaking Jonas is correct, but you too :). I don't like current fpc solution too, but can live with it.

With a little testing, here are two facts:
1) Delphi 7 also shows this bug.
2) Windows.IntersectRect() does not show it, allowing 'misuses'.

So, whoever wrote the FPC function, must have been trying really hard to achieve bug-to-bug compatibility with Delphi... or simply copied their buggy code.

Regards,
Sergei

Reply by email

Jonas Maebe
to Sergei Gorelkin
Sergei Gorelkin wrote 21 lines
zeljko пишет: > On Tuesday 26 October 2010 15:13, Felipe Monteiro de Carvalho wrote: >> On Tue, Oct 26, 2010 at 3:14 PM, zeljko wrote: >>> No, I've opened an issue and Jonas closed with good explanation - >>> we had >>> misusage of IntersectRect in gtk/gtk2 interfaces (I've fixed >>> both) ... so >>> not bug. >> I guess it depends on how you see it. >> >> Anyway, the solution would be trivial, just store the inputs in >> local vars. > I know, but generally speaking Jonas is correct, but you too :). I > don't like current fpc solution too, but can live with it. With a little testing, here are two facts: 1) Delphi 7 also shows this bug. 2) Windows.IntersectRect() does not show it, allowing 'misuses'. So, whoever wrote the FPC function, must have been trying really hard to achieve bug-to-bug compatibility with Delphi... or simply copied their buggy code.

Not necessarily. It's probably a consequence of the person not seeing a reason for first doing everything in a temporary variable and then copying this temporary variable to the destination. Unless you consciously think about the fact that const parameters may be passed by reference, it's easy to make such "mistakes" (although technically, they are not mistakes, but they do make it easier for people using such a function to make error).

Jonas

Reply by email

Sergei Gorelkin
to Jonas Maebe

Jonas Maebe пишет:

Show quoted text 16 lines
> With a little testing, here are two facts: > 1) Delphi 7 also shows this bug. > 2) Windows.IntersectRect() does not show it, allowing 'misuses'. > > So, whoever wrote the FPC function, must have been trying really hard > to achieve bug-to-bug compatibility with Delphi... or simply copied > their buggy code. Not necessarily. It's probably a consequence of the person not seeing a reason for first doing everything in a temporary variable and then copying this temporary variable to the destination. Unless you consciously think about the fact that const parameters may be passed by reference, it's easy to make such "mistakes" (although technically, they are not mistakes, but they do make it easier for people using such a function to make error).

Well, maybe. For me, it is rather hard to think about the opposite - that a const may be passed *not* by reference - due to long-term Delphi/Windows experience.

But, after all, Types.IntersectRect and surrounding stuff were introduced and are intended as WinApi replacement, and WinApi IntersectRect() *does* pass params by reference (they are originally PRect). So maybe it will be still good to fix Types.IntersectRect to conform?

Regards,
Sergei

Reply by email

Michael Van Canneyt
to Sergei Gorelkin
Sergei Gorelkin wrote 25 lines
Jonas Maebe пишет: >> With a little testing, here are two facts: >> 1) Delphi 7 also shows this bug. >> 2) Windows.IntersectRect() does not show it, allowing 'misuses'. >> >> So, whoever wrote the FPC function, must have been trying really hard to >> achieve bug-to-bug compatibility with Delphi... or simply copied their >> buggy code. > > Not necessarily. It's probably a consequence of the person not seeing a > reason for first doing everything in a temporary variable and then copying > this temporary variable to the destination. Unless you consciously think > about the fact that const parameters may be passed by reference, it's easy > to make such "mistakes" (although technically, they are not mistakes, but > they do make it easier for people using such a function to make error). > Well, maybe. For me, it is rather hard to think about the opposite - that a const may be passed *not* by reference - due to long-term Delphi/Windows experience. But, after all, Types.IntersectRect and surrounding stuff were introduced and are intended as WinApi replacement, and WinApi IntersectRect() *does* pass params by reference (they are originally PRect). So maybe it will be still good to fix Types.IntersectRect to conform?

Yes. It should be improved.

Michael.

Reply by email

zeljko
to Sergei Gorelkin: Jonas Maebe пишет: Well, maybe. For me, it is rather hard to think about the…
Sergei Gorelkin wrote 9 lines
Well, maybe. For me, it is rather hard to think about the opposite - that a const may be passed *not* by reference - due to long-term Delphi/Windows experience. But, after all, Types.IntersectRect and surrounding stuff were introduced and are intended as WinApi replacement, and WinApi IntersectRect() *does* pass params by reference (they are originally PRect). So maybe it will be still good to fix Types.IntersectRect to conform?

One note: IntersectRect in lazarus worked OK until we decided to use Types.IntersectRect, old implementation from GraphType looks much better than current fpc one.

zeljko

Reply by email

Mattias Gaertner
to zeljko
Show quoted text 15 lines
On Tuesday 26 October 2010 16:57, Sergei Gorelkin wrote: > > Well, maybe. For me, it is rather hard to think about the opposite - that a > const may be passed *not* by reference - due to long-term Delphi/Windows > experience. > > But, after all, Types.IntersectRect and surrounding stuff were introduced > and are intended as WinApi replacement, and WinApi IntersectRect() *does* > pass params by reference (they are originally PRect). So maybe it will be > still good to fix Types.IntersectRect to conform? One note: IntersectRect in lazarus worked OK until we decided to use Types.IntersectRect, old implementation from GraphType looks much better than current fpc one.

Then it is probably better to undo the change.
Should I do that?

Mattias

Reply by email

Luiz Americo Pereira Camara
to Mattias Gaertner
Mattias Gaertner wrote 12 lines
On Tue, 26 Oct 2010 17:31:48 +0200 zeljko wrote: > One note: IntersectRect in lazarus worked OK until we decided to use > Types.IntersectRect, old implementation from GraphType looks much better than > current fpc one. > Then it is probably better to undo the change. Should I do that?

I think yes, but should be removed when Lazarus uses the fpc with the new IntersectRect version, since even reverting now it will still have the potential to lead to obscure bugs.
In the same program you can have IntersectRect with different behavior just if you switch the uses order LCLIntf Types

PS: I was thinking of removing the other related functions (InflateRect) but gave up since they are also different. I will wait for the next Lazarus release and see first if Types version is Delphi/LCL compatible.

Luiz

Reply by email

Unknown author
to Mattias Gaertner: On Tue, 26 Oct 2010 17:31:48 +0200 Then it is probably better to undo the change. Should…

Quoting Mattias Gaertner :

Show quoted text 23 lines
On Tue, 26 Oct 2010 17:31:48 +0200 zeljko wrote: > On Tuesday 26 October 2010 16:57, Sergei Gorelkin wrote: > > > > > Well, maybe. For me, it is rather hard to think about the > opposite - that a > > const may be passed *not* by reference - due to long-term Delphi/Windows > > experience. > > > > But, after all, Types.IntersectRect and surrounding stuff were introduced > > and are intended as WinApi replacement, and WinApi IntersectRect() *does* > > pass params by reference (they are originally PRect). So maybe it will be > > still good to fix Types.IntersectRect to conform? > > One note: IntersectRect in lazarus worked OK until we decided to use > Types.IntersectRect, old implementation from GraphType looks much > better than > current fpc one. Then it is probably better to undo the change. Should I do that?

No, why ? I've fixed problems inside widgetsets.Let's propose patch for improving Types.IntersectRect().

zeljko

Reply by email

Unknown author
to Luiz Americo Pereira Camara: I think yes, but should be removed when Lazarus uses the fpc with the new IntersectRect…

Quoting Luiz Americo Pereira Camara :

Show quoted text 15 lines
Mattias Gaertner escreveu: > On Tue, 26 Oct 2010 17:31:48 +0200 > zeljko wrote: > > >> One note: IntersectRect in lazarus worked OK until we decided to >> use Types.IntersectRect, old implementation from GraphType looks >> much better than current fpc one. >> > > Then it is probably better to undo the change. > Should I do that? > In the same program you can have IntersectRect with different behavior just if you switch the uses order LCLIntf Types

This is mainly why I don't won't undo IntersectRect() to laz one.Better to propose good patch for Types.IntersectRect().

Reply by email

Luiz Americo Pereira Camara
to Unknown author: Quoting Luiz Americo Pereira Camara : This is mainly why I don't won't undo…
Show quoted text 19 lines
Quoting Luiz Americo Pereira Camara : > Mattias Gaertner escreveu: >> On Tue, 26 Oct 2010 17:31:48 +0200 >> zeljko wrote: >> >> >>> One note: IntersectRect in lazarus worked OK until we decided to >>> use Types.IntersectRect, old implementation from GraphType looks >>> much better than current fpc one. >> >> Then it is probably better to undo the change. >> Should I do that? >> > In the same program you can have IntersectRect with different behavior > just if you switch the uses order LCLIntf Types This is mainly why I don't won't undo IntersectRect() to laz one.Better to propose good patch for Types.IntersectRect().

Since the fixed Types.IntersectRect won't ship with fpc242 anyway the potential for problems will exist.

In the case the LCL version is kept removed, an user code misusing IntersectRect may break since will start to uses the Types version.

In the case the LCL version is restored there's the already cited problem of mixing both.

There's two options IMO if LCL version is removed:
- Fix Types.IntersectRect in 242
- Document the misuse behavior so the user can be warned (my preferred).

Luiz

Reply by email