Sign in Join

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

Mailing lists / fpc-pascal / 2003-08

About order of units...

20 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

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

L D Blake

Ok, still messing with this silly problem...

Now the question is about order of declaration in units...

Lets say I wrote a unit "WinFix" with some of these cursed range checking problems cleaned up... am I correct in assuming that if I added it to my units list like this:

        Uses
          Windows,
          Winfix,
          <my units>;

The dupicate definitions in the WinFix unit would replace those in the Windows unit?

---
L D Blake

Michalis Kamburelis
L D Blake wrote 20 lines
Ok, still messing with this silly problem... Now the question is about order of declaration in units... Lets say I wrote a unit "WinFix" with some of these cursed range checking problems cleaned up... am I correct in assuming that if I added it to my units list like this: Uses Windows, Winfix, <my units>; The dupicate definitions in the WinFix unit would replace those in the Windows unit? --- L D Blake

Yes. Identifiers in Windows unit will be hidden by same identifiers in WinFix unit.

Beware of one "catch" : if you have two functions/procedures with the same names, one in the Windows unit and one in the WinFix unit _and they are declared as overloaded_ (i.e. using Delphi's style, with "overload" keyword) then Delphi and FPC 1.1 will be doing "cross-unit overloading" - this is the only case when identifier from WinFix will NOT hide the same identifier from Windows, intead they will co-exist in one namespace. However, this is not implemented in FPC 1.0.x so if you use only FPC 1.0.x there's nothing to worry (however you should be aware of this if you're writing some non-testing code, that you might want to compile some day with FPC 1.1 or higher).

Regards,
Michalis Kamburelis

http://www.camelot.homedns.org/~michalis/

L D Blake
to Michalis Kamburelis

In reply to your message of August 30, 2003

Yes. Identifiers in Windows unit will be hidden by same identifiers in WinFix unit.

Ok... I was pretty sure that would work. And as you point out so well I'm aware that it's real problem here is types declared in the windows unit where, as I pointed out previously, LongInt has been confused with BYTE, WORD and LONGWORD types... In continuing to fuss with this I checked the definitions of several structures in struct.inc and found the MSG declaration corrupted...

     MSG = record
          hwnd : HWND;
          message : UINT;
          wParam : WPARAM;
          lParam : LPARAM;
          time : DWORD;
          pt : POINT;
       end;

In Base.inc ... HWND is defined as a longint, wparam is cardinal, lparam is longint and dword is cardinal. Not only could this result in negative message numbers being passed to windproc or defwndproc, it could result in message packets of varying sizes... disastrous when you realize windows is accessing variables as an offset from a pointer.

Redeclaring MSG in my own code as

    MSG = record
          hwnd    : LongWord;
          message : LongInt;
          wParam  : LongWord;
          lParam  : LongWord;
          time    : LongWord;
          pt      : POINT;
       end;

Got me an almost 3 hour run before my software messed up again.

Looking furter for the message declarations (wm_command etc.), message.inc reveals several blocks like this:

     NM_CLICK = -(2);
     NM_DBLCLK = -(3);
     NM_KILLFOCUS = -(8);
     NM_OUTOFMEMORY = -(1);
     NM_RCLICK = -(5);
     NM_RDBLCLK = -(6);
     NM_RETURN = -(4);
     NM_SETFOCUS = -(7);

Now, not only do we have the possibility of negative handles, we have negative values for messages? Are these values correct or are these the result of futzing about trying to get around the incorrect declarations?

-----
L D Blake

Peter Vreman
to Michalis Kamburelis: Yes. Identifiers in Windows unit will be hidden by same identifiers in WinFix unit.…
Show quoted text 5 lines
intead they will co-exist in one namespace. However, this is not implemented in FPC 1.0.x so if you use only FPC 1.0.x there's nothing to worry (however you should be aware of this if you're writing some non-testing code, that you might want to compile some day with FPC 1.1 or higher).

FPC 1.1 also has the HWND defined as DWord

Peter

Marco van de Voort
to L D Blake: In reply to your message of August 30, 2003 Ok... I was pretty sure that would work. And…
The real problem here is types declared in the windows unit where, as I pointed out previously, LongInt has been confused with BYTE, WORD and LONGWORD types...

Can you name examples of that?

Most notably about byte's and word's confusion (so places where types have a different size then they should have, regardless of signedness)

Signedness only generates range checks, and shouldn't be a problem otherwise.

L D Blake
to Marco van de Voort

In reply to your message of August 30, 2003

Show quoted text 8 lines
> The real problem here is types declared in the windows unit where, as I > pointed out previously, LongInt has been confused with BYTE, WORD and LONGWORD > types... Can you name examples of that? Most notably about byte's and word's confusion (so places where types have a different size then they should have, regardless of signedness)

From base.inc ...
{ was #define dname(params) def_expr }
{ argument types are unknown }

  function HIBYTE(w : longint) : BYTE;

Should be hibyte(w : word) : byte; according to the SDK.

  { was #define dname(params) def_expr }
  { argument types are unknown }
  function HIWORD(l : longint) : WORD;
Should be hiword(l : longword) : word;
  { was #define dname(params) def_expr }
  { argument types are unknown }
  function LOBYTE(w : longint) : BYTE;
Should be lobyte(w : word) : byte;
  { was #define dname(params) def_expr }
  { argument types are unknown }
  function LOWORD(l : longint) : WORD;
Should be lowword(l : longword) : word;
  { was #define dname(params) def_expr }
  { argument types are unknown }
  function MAKEWORD(a,b : longint) : WORD;
Should be makeword(a,b : byte) : word;
  { was #define dname(params) def_expr }
  { argument types are unknown }
  function GetBValue(rgb : longint) : BYTE;
Should be getbvalue(rgb : longword) : byte;
  { was #define dname(params) def_expr }
  { argument types are unknown }
  function GetGValue(rgb : longint) : BYTE;
Should be getgvalue(rgb : longword) : byte;
  { was #define dname(params) def_expr }
  { argument types are unknown }
  function GetRValue(rgb : longint) : BYTE;
Should be getrvalue (rgb : longword) : byte;
  { was #define dname(params) def_expr }
  { argument types are unknown }
  function RGB(r,g,b : longint) : DWORD;
Should be rgb(r,g,b : byte) : longword;

That's only in BASE.INC, there are literally *hundreds* of other places where this happens... It's all through the whole windows unit. It's also common in both the record and function declarations as well... I did a quick search for "longint" in the wininc directory and got over 1000 returns, all of which are now suspect.

Signedness only generates range checks, and shouldn't be a problem otherwise.

Well, unless you want to actually produce error free code, that is.

-----
L D Blake

L D Blake
to Marco van de Voort: Can you name examples of that? Most notably about byte's and word's confusion (so places…

In reply to your message of August 30, 2003

Show quoted text 5 lines
> The real problem here is types declared in the windows unit where, as I > pointed out previously, LongInt has been confused with BYTE, WORD and LONGWORD > types... Can you name examples of that?

A little more information ... I just ran h2pas on a couple of header files from the SDK... It created a file just like the examples I gave you... bytes, words, longwords... all replaced by LongInt.

-----
L D Blake

Peter Vreman
to L D Blake
Show quoted text 10 lines
>> The real problem here is types declared in the windows unit where, as I >> pointed out previously, LongInt has been confused with BYTE, WORD and LONGWORD >> types... > Can you name examples of that? A little more information ... I just ran h2pas on a couple of header files from the SDK... It created a file just like the examples I gave you... bytes, words, longwords... all replaced by LongInt.

h2pas is only a helper program that does the major part of C header translation. It uses longint by default as parameter type for macro's. When you want to have correct macro's you need to create/edit them manualy.

Peter

L D Blake
to Peter Vreman

In reply to your message of August 30, 2003

h2pas is only a helper program that does the major part of C header translation. It uses longint by default as parameter type for macro's. When you want to have correct macro's you need to create/edit them manualy.

Yep... I know. But it occurs to me that whoever did the conversion didn't check very carefully.

-----
L D Blake

Peter Vreman
to L D Blake
Show quoted text 8 lines
> h2pas is only a helper program that does the major part of C header > translation. It uses longint by default as parameter type for > macro's. When you want to have correct macro's you need to create/edit > them manualy. Yep... I know. But it occurs to me that whoever did the conversion didn't check very carefully.

When the windows unit was created it was more important to get the compiler running correct natively under windows. After that nobody took care of walking the whole windows unit because it is a boring job to do. The windows unit worked for us and the users didn't report problems so it stayed that way. The current developpers have other priorities that they want to do than updating the windows unit. FPC is open source so you are welcome to supply patches to fix the windows unit.

Peter

Unknown author
to L D Blake: In reply to your message of August 30, 2003 From base.inc ... { was #define dname(params)…

From: L D Blake
Organization: Secret society to end secret societies To: Marco van de Voort
Subject: Re: [fpc-pascal]About order of units... Send reply to:
Date sent: Sat, 30 Aug 2003 15:29:48 -0400

Show quoted text 14 lines
From base.inc ... { was #define dname(params) def_expr } { argument types are unknown } function HIBYTE(w : longint) : BYTE; Should be hibyte(w : word) : byte; according to the SDK. { was #define dname(params) def_expr } { argument types are unknown } function HIWORD(l : longint) : WORD; Should be hiword(l : longword) : word;

.
.

If you have a look at the implementation, you'll quickly find, that all of the examples you listed in this mail make absolutely _no_ difference. For example:
----------

  function HIBYTE(w : longint) : BYTE;
    begin
       HIBYTE:=BYTE(((WORD(w)) shr 8) and $FF);
    end;

---------
The first thing being done with the supplied argument is type casting to a word. BTW, at least some of these macros could probably be implemented more efficiently using some pointer arithmetics, but that's a different story.

Tomas

L D Blake
to Unknown author

In reply to your message of August 31, 2003

If you have a look at the implementation, you'll quickly find, that all of the examples you listed in this mail make absolutely _no_ difference.

It DOES matter, especially in structures where windows is accessing things as an offset from a pointer. Typing something as a 4 byte variable instead of a 1 or 2 byte one will result in wrong structure sizes causing all kinds of errors inside windows where we can't really trace them down... The same is true of parameters passed in API calls, hand it 4 bytes instead of 1 or 2 and you've just offset the rest of the parameters, causing errors, never mind the potential for passing grossly incorrect data... and I'm pretty sure that's what I've got going on.

As I explained earlier... I'm getting re-draw errors. Not only is my project losing it's title bars, it is redrawing window frames in the wrong places and sometimes it redraws the wrong window altogether... Try moving one window and it draws the frame of a different window in the wrong place on the screen.

If I turn on range checking I get a 201 error (range check) from my program every time I try to open an HTML file (i.e. the FP docs) in IE... This is especially weird since int's only HTML and only in IE... nothing else. And I get hundreds of Range errors as the program runs (it's mostly api calls at this point).

Errors like these from supplied units is a serious impediment to the developement of bug free, reliable software, which is what Pascal is supposed to be all about. It's strength is in it's rigid error checking.

-----
L D Blake

L D Blake
to Peter Vreman: When the windows unit was created it was more important to get the compiler running…

In reply to your message of August 31, 2003

Show quoted text 10 lines
>Yep... I know. But it occurs to me that whoever did the conversion didn't >check very carefully. When the windows unit was created it was more important to get the compiler running correct natively under windows. After that nobody took care of walking the whole windows unit because it is a boring job to do. The windows unit worked for us and the users didn't report problems so it stayed that way. The current developpers have other priorities that they want to do than updating the windows unit. FPC is open source so you are welcome to supply patches to fix the windows unit.

I am still learning here, Peter... I know TP 5 from years ago, I know windows from last month and I haven't even ventured in to OOP yet... I really don't think myself qualified to take on a big job like this, at least not right now.

That said... I will be happy to work with, perhaps coordinate, a group of more advanced FP users who DO want to take on the task of improving the unit. I have the time (and hopefully the patience) to go through the source and find all the obvious errors, perhaps even do some minor bug fixing. If a couple of others would like to help with compiling (I can't get this unit to compile to save my soul!) and testing maybe we can get the job done.

But then... that's a 5 year old unit that never had any real testing or developement, it might actually be worthwhile to reconstruct the unit from scratch. The new Platform SDK from Microsoft has all the .h files for nt4, 2000, xp, and 2003 in it, including support for transparency, overlays, xp styles, and a bunch of nifty new controls that are in the current versions but are not supported by FP. It might actually make more sense to start over rather than simply patching up an antique.

Anyone who'd be willing to take this on can contact me privately as and we can at least discuss the idea.

-----
L D Blake

Michalis Kamburelis
to L D Blake: In reply to your message of August 31, 2003 It DOES matter, especially in structures…
L D Blake wrote 17 lines
In reply to your message of August 31, 2003 >If you have a look at the implementation, you'll quickly find, that >all of the examples you listed in this mail make absolutely _no_ >difference. It DOES matter, especially in structures where windows is accessing things as an offset from a pointer. Typing something as a 4 byte variable instead of a 1 or 2 byte one will result in wrong structure sizes causing all kinds of errors inside windows where we can't really trace them down... The same is true of parameters passed in API calls, hand it 4 bytes instead of 1 or 2 and you've just offset the rest of the parameters, causing errors, never mind the potential for passing grossly incorrect data... and I'm pretty sure that's what I've got going on.

...

L D Blake

No, L.D. Blake, it doesn't matter. Tomas was right. All the things that you showed as having bad parameters are _macros_, not _API calls_. This is why h2pas generated "LongInt" types for theses parameters. And this is also the reason why it doesn't hurt : even if WinAPI docs states that some macro takes Byte as parameter (which is just a specification of the "proper use of the macro", because in actual C code macro's parameters have no assigned type), and in our Windows unit it takes LongInt (and than casts it in the implementation to Byte before doing some bit-shifts) it will not cause any errors. Because this is a macro: it is basically just some utility routine that is written and compiled in FreePascal. It is NOT something that is called from some Windows system DLLs. So even if we have LongInt parameters where WinAPI Help states that these should be Byte - it doesn't hurt, it will not cause any errors.

In response to your next letter (that I just received), I can guarantee you that Windows unit IS extensively used and it is tested all the time. It is a base unit for many other units in FPC, some of them multi-platform, some of them Windows-specific. I simply think you're on a bad track suspecting that your problems are originated from some bugs in Windows unit.

Regards,

L D Blake
to Michalis Kamburelis

In reply to your message of August 31, 2003

I simply think you're on a bad track suspecting that your problems are originated from some bugs in Windows unit.

Ok, I can accept that... but now I'm left to wonder what is causing all those bizarre range checking errors and why my project's screens draw as they do. The most puzzling is how launching a file in a completely different program can cause range checking errors in mine. There is definately something damned weird going on... but where, and why?

I gotta confess, if it's not the windows unit, I have absolutely no clue what the problem is... I've been over my own code, checked declarations, disabled and rewritten things and nothing changes the errors I'm getting. Nothing eliminates the errors, nothing prevents the screen from getting scrambled and I'm not going to finalize a project that won't run with overflow, stack, and range checking turned on and I'm certainly not going to finalize one that bombs out when other windows are opened...

-----
L D Blake

Jonas Maebe
to L D Blake
L D Blake wrote
Ok, I can accept that... but now I'm left to wonder what is causing all those bizarre range checking errors

At least some of the range check errors are due to errors in the Windows unit (mingling cardinals=dwords and longints). However, these are not errors that will change the course of your program in any way, as the data passed around doesn't change because of these typings. It's of course possible you have other range errors in your program as well, but that you can't discover them because it bombs out earlier because of the windows unit mess.

Have you already tried using -ghl to check for memory errors?

Jonas

L D Blake
to Jonas Maebe

In reply to your message of August 31, 2003

Show quoted text 7 lines
At least some of the range check errors are due to errors in the Windows unit (mingling cardinals=dwords and longints). However, these are not errors that will change the course of your program in any way, as the data passed around doesn't change because of these typings. It's of course possible you have other range errors in your program as well, but that you can't discover them because it bombs out earlier because of the windows unit mess.

Exactly... I want to find MY mistakes... but I am being hindered because of the errors occuring elswhere. I'm aware that most of the errors won't affect performance but they do make a mess of my own efforts to perfect my code.

Have you already tried using -ghl to check for memory errors?

No not yet... but I will. The program is only 66k (so far) so I doubt I'm having memory problems in a 256meg machine, but you never know.

FWIW... I think I've found one of the problems. I'm using a scrollbar as a song position indicator, commenting out the code that enables and disables that particular child window seems to get rid of the screen scattering problem... so I have to look much more closely at the way I'm manipulating it.

Of course I still get a gazillion range checking errors which isn't helping me find the other problems and I still get that pesky range error from my proggy whenever I open the FP docs... This is why I was suggesting that maybe we (?) should look into updating the windows unit... get it to match the SDK specs and add in the new controls for 2k, xp and 03 while L D Blake

Unknown author
to L D Blake: In reply to your message of August 31, 2003 Ok, I can accept that... but now I'm left to…

From: L D Blake
Organization: Secret society to end secret societies To: Michalis Kamburelis
Subject: Re: [fpc-pascal]About order of units... Send reply to:
Date sent: Sun, 31 Aug 2003 14:40:33 -0400

Show quoted text 8 lines
> I simply think you're on > a bad track suspecting that your problems are originated from some > bugs in Windows unit. Ok, I can accept that... but now I'm left to wonder what is causing all those bizarre range checking errors and why my project's screens draw as they do. The most puzzling is how launching a file in a completely different program can cause range checking errors in mine.

I have one idea (although I'm no windows programmer). How do you play sound files - using some kind of your own code, or relying on default Windows handlers (i.e. installed Windows codecs)? If it's the latter, you might be possibly using IE for playing your sound files even without knowing it. That might be a possibility how starting IE might influence your program.

Tomas

L D Blake
to Unknown author

In reply to your message of August 31, 2003

Show quoted text 6 lines
I have one idea (although I'm no windows programmer). How do you play sound files - using some kind of your own code, or relying on default Windows handlers (i.e. installed Windows codecs)? If it's the latter, you might be possibly using IE for playing your sound files even without knowing it. That might be a possibility how starting IE might influence your program.

Sound play is done through the MMSYSTEM unit, which is the interface to MCI (i.e. Codecs). I had no idea that IE might be involved... but it might explain one more of the problems... I might actually be running afoul of my pop-up killer by trying to open two ie windows at once ... now wouldn't that be a laugh!

Can anyone confirm if IE would be involved when playing midi, wmi, wave, and mp3 audio files?

-----
L D Blake

Unknown author
to L D Blake

From: L D Blake
Organization: Secret society to end secret societies To: ""
Subject: Re: [fpc-pascal]About order of units... Send reply to:
Date sent: Sun, 31 Aug 2003 18:26:04 -0400

Show quoted text 15 lines
> I have one idea (although I'm no windows programmer). How do you > play sound files - using some kind of your own code, or relying on > default Windows handlers (i.e. installed Windows codecs)? If it's > the latter, you might be possibly using IE for playing your sound > files even without knowing it. That might be a possibility how > starting IE might influence your program. Sound play is done through the MMSYSTEM unit, which is the interface to MCI (i.e. Codecs). I had no idea that IE might be involved... but it might explain one more of the problems... I might actually be running afoul of my pop-up killer by trying to open two ie windows at once ... now wouldn't that be a laugh! Can anyone confirm if IE would be involved when playing midi, wmi, wave, and mp3 audio files?

IE _can_ be involved. Whether it really is or not might depend on your configuration (installed software and default handlers). You could probably try to install WinAmp, allow it to bind all supported formats to itself, and check whether the behaviour is the same as before (I'd probably try it with mp3). I don't know, whether this really overrides IE completely, but hopefully it should.

Tomas