Windows API definitions/prototypes lazarus / 62-General ---------------------------------------------------------------------- 440bx · 2019-02-04 13:02 Hello, I'd like to know if there is some reason not to change some API definitions such as: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function BeginPaint(hWnd: HWND; var lpPaint: TPaintStruct): HDC; external 'user32' name 'BeginPaint';to: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 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. ---------------------------------------------------------------------- marcov · 2019-02-04 13:30 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 · 2019-02-04 13:39 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" ---------------------------------------------------------------------- 440bx · 2019-02-04 14:06 @Marcov: Quote from: marcov on February 04, 2019, 02:30:14 pmAfaik  - 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. ---------------------------------------------------------------------- marcov · 2019-02-04 14:20 Quote from: 440bx on February 04, 2019, 03:06:01 pmNo 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 · 2019-02-04 14:40 Quote from: marcov on February 04, 2019, 03:20:55 pmBut 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.. .  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. ---------------------------------------------------------------------- marcov · 2019-02-04 14:47 Quote from: 440bx on February 04, 2019, 03:40:46 pmHere 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 · 2019-02-04 14:55 Quote from: marcov on February 04, 2019, 03:47:45 pmI'm not interested. Doing some, and some not will only invite more discussion. Fair enough.  Thank you for being clear about that. ---------------------------------------------------------------------- Thaddy · 2019-02-04 16:23 Quote from: 440bx on February 04, 2019, 03:06:01 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program default;{$mode delphi}procedure testme(out value:integer);begin  value := value; // variable not initialized: needs to be done locally in the procedure!!!end;procedure testme2(var value:integer);begin  value := value; // no warning: compiler assumes value is already initialized on call!!end;var  a:integer = 4;begin   testme(a); // triggers warning   writeln(a);   testme2(a); // does not trigger warning   writeln(a);end.If you try to compile with -Sew you will see the effect the best.  Code: Bash  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i $ fpc -Sew default.pasFree Pascal Compiler version 3.3.1-r41217 [2019/02/04] for armCopyright (c) 1993-2018 by Florian Klaempfl and othersTarget OS: Linux for ARMHFCompiling default.pasdefault.pas(5,12) Warning: Variable "value" does not seem to be initializeddefault.pas(19) Fatal: There were 1 errors compiling module, stoppingFatal: Compilation abortedError: /usr/local/bin/ppcarm returned an error exitcode 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..... ---------------------------------------------------------------------- Thaddy · 2019-02-04 21:21 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. ---------------------------------------------------------------------- marcov · 2019-02-04 21:24 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 · 2019-02-04 21:30 Quote from: marcov on February 04, 2019, 10:24:28 pmSome 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. ---------------------------------------------------------------------- 440bx · 2019-02-04 22:48 Quote from: Thaddy on February 04, 2019, 10:30:13 pmI 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. ---------------------------------------------------------------------- PascalDragon · 2019-02-05 08:12 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 · 2019-02-05 08:29 Yes, forgot to explain that. ---------------------------------------------------------------------- ASerge · 2019-02-05 12:05 Quote from: PascalDragon on February 05, 2019, 09:12:44 amFor external APIs that don't use managed types (e.g. those Windows APIs that do not use interfaces) there shouldn't be a difference. That is, it turns out that the conversion in the Windows API "var" to "out" constraints only a large amount of work, and there are no other reasons. ---------------------------------------------------------------------- BeniBela · 2019-02-05 12:38 Quote from: 440bx on February 04, 2019, 03:40:46 pmHere 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. That would be really helpful I had already opened a bug report for this ---------------------------------------------------------------------- 440bx · 2019-02-05 13:17 Quote from: BeniBela on February 05, 2019, 01:38:52 pmThat would be really helpful I certainly understand the developers reluctance of doing it as a "project" assigned to one individual.  In the case of FPC, it seems to me that the FPC/Lazarus user community could "pitch in" cleaned up definitions and little by little end up with definitions that are as clean as they can be, It would be rather nice too if the contributor included some simple program (in many cases a short console program) that would exercise the definition(s) being contributed to demonstrate the new definition(s) is/are correct.    Maybe establishing some rules of how such specific contributions must be made would help.  After all, it is a fact that there has to be - should be - one individual to verify and accept the contribution and, it's important to make that individual's job as simple and straightforward as possible. The beauty of open source is that everyone can contribute and the aggregate of many small contributions often lead to a better result than one individual could ever achieve.  I believe we should take advantage of that and create "structures" to submit and validate specific changes - such as API declarations. Just thinking out loud...