Recent

Author Topic: Windows API definitions/prototypes  (Read 1885 times)

440bx

  • Hero Member
  • *****
  • Posts: 1129
Windows API definitions/prototypes
« on: February 04, 2019, 02:02:47 pm »
Hello,

I'd like to know if there is some reason not to change some API definitions such as:
Code: Pascal  [Select]
  1. function BeginPaint(hWnd: HWND; var lpPaint: TPaintStruct): HDC; external 'user32' name 'BeginPaint';
to:
Code: Pascal  [Select]
  1. function BeginPaint(hWnd: HWND; out lpPaint: TPaintStruct): HDC; external 'user32' name 'BeginPaint';

changing "var" to "out" would cause the compiler to no longer issue warnings about the parameter possibly not being initialized. 

The definition would seem cleaner that way but, I am concerned that I may be missing a good reason to keep it as a "var".

That's the question: is there some good reason why such parameters should be kept as "var" instead of changed to "out" ? are there potential undesirable side effects from it ?

Thank you for your help.


using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7446
Re: Windows API definitions/prototypes
« Reply #1 on: February 04, 2019, 02:30:14 pm »
Afaik
 - for ref counted types it is different.
 - Enormous amount of work, chances on bug introduction. (and before you easily step over this, we are still committing bugfixes every month from the initial translation in 1999)

Moreover most people only have a few lines of API code. If they care that much, turn warnings off for that piece of code.

Thaddy

  • Hero Member
  • *****
  • Posts: 8928
Re: Windows API definitions/prototypes
« Reply #2 on: February 04, 2019, 02:39:31 pm »
That's correct. It also would break genormous amounts of external code, including much legacy Delphi code.
The real fix is imho that the external keyword should trigger a "ignore the warning"
Most people that want to use threading should learn to patch their jeans first: use a needle.

440bx

  • Hero Member
  • *****
  • Posts: 1129
Re: Windows API definitions/prototypes
« Reply #3 on: February 04, 2019, 03:06:01 pm »
@Marcov:

Afaik
 - for ref counted types it is different.
 - Enormous amount of work, chances on bug introduction. (and before you easily step over this, we are still committing bugfixes every month from the initial translation in 1999)

Moreover most people only have a few lines of API code. If they care that much, turn warnings off for that piece of code.
No argument about the fact that it does represent a significant amount of work and, of course, any change has the potential of introducing unforeseen bugs.

It's a bit of "problem" when one's entire program is pure API.  Lots of warnings and it's probably more work to turn of the warnings than to change the API definitions.


@Thaddy:

can you give an example of what code would be broken ?... as far as I can tell, the only difference between a "var" parameter and an "out" parameter is that "out" informs the compiler that the parameter will be written to and not just read.   What happens to the parameter does not change.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7446
Re: Windows API definitions/prototypes
« Reply #4 on: February 04, 2019, 03:20:55 pm »
No argument about the fact that it does represent a significant amount of work and, of course, any change has the potential of introducing unforeseen bugs.


It's a bit of "problem" when one's entire program is pure API.  Lots of warnings and it's probably more work to turn of the warnings than to change the API definitions.

I can see that. But then I think it is better for such cases that those manage their own API (e.g. new automated translations), than doing manually such huge changes to the currently hand maintained ones.  That is simply not an option.

Good luck!

440bx

  • Hero Member
  • *****
  • Posts: 1129
Re: Windows API definitions/prototypes
« Reply #5 on: February 04, 2019, 03:40:46 pm »
But then I think it is better for such cases that those manage their own API (e.g. new automated translations), than doing manually such huge changes to the currently hand maintained ones.  That is simply not an option.

Good luck!
Thank you.. <chuckle>. 

Here is a related question,  if I were to change the definitions of those APIs I use in my programs (IOW, the changes would be manual and individually tested to be correct), would there be any interested in including the "cleaned up" definitions of those APIs ?  (this question is _mostly_ to determine if any effort on my part in that regard could benefit other people, if it wouldn't then, I would most likely not do it.)

Obviously, the number of APIs I would update would also be very limited compared to the number of APIs available.  I doubt it would exceed a few hundreds at most.

using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7446
Re: Windows API definitions/prototypes
« Reply #6 on: February 04, 2019, 03:47:45 pm »
Here is a related question,  if I were to change the definitions of those APIs I use in my programs (IOW, the changes would be manual and individually tested to be correct), would there be any interested in including the "cleaned up" definitions of those APIs ?  (this question is _mostly_ to determine if any effort on my part in that regard could benefit other people, if it wouldn't then, I would most likely not do it.)

Obviously, the number of APIs I would update would also be very limited compared to the number of APIs available.  I doubt it would exceed a few hundreds at most.

I'm not interested. Doing some, and some not will only invite more discussion.

440bx

  • Hero Member
  • *****
  • Posts: 1129
Re: Windows API definitions/prototypes
« Reply #7 on: February 04, 2019, 03:55:43 pm »
I'm not interested. Doing some, and some not will only invite more discussion.
Fair enough.  Thank you for being clear about that.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 8928
Re: Windows API definitions/prototypes
« Reply #8 on: February 04, 2019, 05:23:56 pm »
@Thaddy:

can you give an example of what code would be broken ?... as far as I can tell, the only difference between a "var" parameter and an "out" parameter is that "out" informs the compiler that the parameter will be written to and not just read.   What happens to the parameter does not change.
Out is initialization from within a method or procedure. Var does not .... They are distinctly different. Out is more strict than var. Although out is compatible with var, but not every var with out.
The use of out leads to safer programming. Will add example later.
[edit] Simple example:
Code: Pascal  [Select]
  1. program default;
  2. {$mode delphi}
  3. procedure testme(out value:integer);
  4. begin
  5.   value := value; // variable not initialized: needs to be done locally in the procedure!!!
  6. end;
  7. procedure testme2(var value:integer);
  8. begin
  9.   value := value; // no warning: compiler assumes value is already initialized on call!!
  10. end;
  11. var
  12.   a:integer = 4;
  13. begin
  14.    testme(a); // triggers warning
  15.    writeln(a);
  16.    testme2(a); // does not trigger warning
  17.    writeln(a);
  18. end.
If you try to compile with -Sew you will see the effect the best.  O:-) 8-) ;D
Code: Bash  [Select]
  1. $ fpc -Sew default.pas
  2. Free Pascal Compiler version 3.3.1-r41217 [2019/02/04] for arm
  3. Copyright (c) 1993-2018 by Florian Klaempfl and others
  4. Target OS: Linux for ARMHF
  5. Compiling default.pas
  6. default.pas(5,12) Warning: Variable "value" does not seem to be initialized
  7. default.pas(19) Fatal: There were 1 errors compiling module, stopping
  8. Fatal: Compilation aborted
  9. Error: /usr/local/bin/ppcarm returned an error exitcode
  10.  
So that's what happens to the parameter if it does not change.
Does that clarify the issue?
I can't explain it any simpler than this.....
« Last Edit: February 04, 2019, 05:48:22 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

Thaddy

  • Hero Member
  • *****
  • Posts: 8928
Re: Windows API definitions/prototypes
« Reply #9 on: February 04, 2019, 10:21:22 pm »
Actually I can:
- out has only a one way valid value, literally out only. Any value before assigning a value to the out parameter inside a method technically looses its value and the behavior is otherwise is undefined and implementation can vary.
- var is a two way value. If a method does or does not change the value it is still always valid.

So if you compile the above example and do not pay attention to the warning both will print 4, but that is by accident.
The example reveals the warning! as demonstrated if you tell the compiler to treat warnings as errors ( -Sew):
In that case the program will not even compile.
« Last Edit: February 04, 2019, 10:37:00 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7446
Re: Windows API definitions/prototypes
« Reply #10 on: February 04, 2019, 10:24:28 pm »
Some windows apis have macros that specify if the parameter is in, out or inout.

At least e.g. commctrl and mmsysten afaik do. I'm not sure if older apis also do.

Thaddy

  • Hero Member
  • *****
  • Posts: 8928
Re: Windows API definitions/prototypes
« Reply #11 on: February 04, 2019, 10:30:13 pm »
Some windows apis have macros that specify if the parameter is in, out or inout.

At least e.g. commctrl and mmsysten afaik do. I'm not sure if older apis also do.
This has not always been the case: only when the MS compilers were able to support this. So MS rewrote / redocumented their API's at that point.
Currently most current API's always use it. They are not "empty" Macro's, they actually trigger, just like FPC does trigger the warning.
I hope you agree with my explanation and example, btw.
« Last Edit: February 04, 2019, 10:33:27 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

440bx

  • Hero Member
  • *****
  • Posts: 1129
Re: Windows API definitions/prototypes
« Reply #12 on: February 04, 2019, 11:48:56 pm »
I hope you agree with my explanation and example, btw.
But of course!

BTW, your presumption that the "compiler assumes value is already initialized on call!!" is very funny. 

Try not initializing the variable "a" to see how much the compiler "assumes"  ... you're funny!

When you tell the compiler that a parameter is "out", you are telling the compiler that the parameter will be written to (assigning it to itself doesn't qualify as writing to it - it's a bit unusual to have to "clarify" this "mystifying" fact.)

"var" only tells the compiler to pass the variable by reference.  It does not tell the compiler how the variable should be used (read or written.)  It doesn't tell the compiler to "assume" anything.

Thank you for the entertainment.  :D

 
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 626
  • Compiler Developer
Re: Windows API definitions/prototypes
« Reply #13 on: February 05, 2019, 09:12:44 am »
One important difference between var and out is that the latter finalizes a variable of a managed type (e.g. decreases the reference count on a AnsiString/UnicodeString). This can lead to different and unexpected behaviour (there was some discussion about this in the past on the mailing lists, but I'd need to find that again... :-[ ).
For external APIs that don't use managed types (e.g. those Windows APIs that do not use interfaces) there shouldn't be a difference.

Thaddy

  • Hero Member
  • *****
  • Posts: 8928
Re: Windows API definitions/prototypes
« Reply #14 on: February 05, 2019, 09:29:14 am »
Yes, forgot to explain that.
Most people that want to use threading should learn to patch their jeans first: use a needle.