Recent

Author Topic: Warning on identifier usage ?  (Read 1986 times)

440bx

  • Hero Member
  • *****
  • Posts: 5137
Warning on identifier usage ?
« on: March 25, 2025, 06:58:05 pm »
Hello,

It is quite common in Windows programming to run into functions, types and constant definitions that are valid _only_ for a Windows version greater than or equal to "someversion".

For instance, VirtualAlloc2 is only available in Windows 10 or above.

I would like to have FPC emit a warning or hint when it sees that VirtualAlloc2 is used.  Something along the lines of "VirtualAlloc2 requires Windows 10 or greater".   

The question is: is it possible to make FPC emit such a message upon seeing that VirtualAlloc2 is used ? if yes, how ? also, ideally, the message could be emitted for other things such as constants, enumerations or any other identifier that requires a version of Windows greater than or equal to some version.

Thank you for your help.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 16781
  • Ceterum censeo Trump esse delendam
Re: Warning on identifier usage ?
« Reply #1 on: March 25, 2025, 07:08:31 pm »
Some of MS own compilers simply crash at runtime.. That's also a way.
Theoretically it is possible to create the windows units so that functions procedures and structs, etc, are protected by a windows version check.
Quite a lot of work...rearranging blocks of functionality per windows release.
Unless you encounter it and fix it yourself on a per occurrance base, subsequently providing a patch for it. Otherwise this is not feasable for the core team.

So I suggest that you provide a patch for the issue you mentioned: that will likely be applied and can serve as a template for further occurances.
Such a patch is not difficult, but without grouping functionality per version can likely slow down parsing of the win units considerably.
« Last Edit: March 25, 2025, 07:12:42 pm by Thaddy »
Changing servers. thaddy.com may be temporary unreachable but restored when the domain name transfer is done.

440bx

  • Hero Member
  • *****
  • Posts: 5137
Re: Warning on identifier usage ?
« Reply #2 on: March 25, 2025, 07:47:43 pm »
I had in mind something functionally equivalent to the definition below (I know this cannot be done now exactly as I am going to show it but, I wonder if there isn't an alternate way of doing it as of now.)

Code: Pascal  [Select][+][-]
  1. { VirtualAlloc2 definition }
  2.  
  3. function VirtualAlloc2(parameter1 : parameter1_type;
  4.                        parameter2 : parameter2_type;
  5.                        <etc>)
  6.          : return_value; onuse "VirtualAlloc2 requires Windows 10 version 1607 or greater".
  7.  
that would be a way to inform the compiler to emit a message when it sees VirtualAlloc2 is used.  Obviously, there is no "onuse" clause as of now but, I'm wondering if the same effect can be achieved using current FPC facilities.

Basically a way to associate a compiler message with the use of a function/procedure/<any type, or record field>

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10997
  • Debugger - SynEdit - and more
    • wiki
Re: Warning on identifier usage ?
« Reply #3 on: March 25, 2025, 07:53:55 pm »
you can add "deprecated 'text';

There are also "experimental", "platform" and "unimplemented" (but not sure if they take custom text)

440bx

  • Hero Member
  • *****
  • Posts: 5137
Re: Warning on identifier usage ?
« Reply #4 on: March 25, 2025, 08:03:36 pm »
Thank you Martin.

Just checked, "deprecated" accepts a string constant, the other ones don't. 

The downside of using "deprecated" is that the item may not necessarily be deprecated in this case.

Since what I have in mind is very close to the current functionality of "deprecated", I wonder if the developers would consider a feature request for something that works like "deprecated" but that does not state the item is deprecated, e.g, "onuse".

Maybe PascalDragon will see this post and give an opinion.

Thanks again.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 16781
  • Ceterum censeo Trump esse delendam
Re: Warning on identifier usage ?
« Reply #5 on: March 25, 2025, 10:26:12 pm »
The problem is that this is a runtime issue and not a compile time issue.
"deprecated", "experimental", "platform" and "unimplemented" are all compile time!

FPC can compile code with old machines for machines that have way more advanced CPU's: e.g. the notebook I am writing this on has no simd avx512, but I can compile for it! On the olden hardware....(can't run it, though ;) )

Best thing I can think of is throw a warning or hint at compile time:
Code: Pascal  [Select][+][-]
  1. program dumb;
  2. {$push}{$warnings on}{$warning 'somefunc is only Windows10 or higher'}
  3. procedure somefunc(constref x: int32);external;
  4. {$pop}
  5. begin
  6. end.
That way, if the programmer knows its hardware/platform bottom line, you can compile with -Sewh to debug such things.
« Last Edit: March 25, 2025, 10:49:53 pm by Thaddy »
Changing servers. thaddy.com may be temporary unreachable but restored when the domain name transfer is done.

n7800

  • Sr. Member
  • ****
  • Posts: 280
Re: Warning on identifier usage ?
« Reply #6 on: March 25, 2025, 11:21:37 pm »
Yes, I also wanted to clarify the point about compile time and run time:



1. At run time

In this case, it can be done in the Windows module itself. In the initialization section, it can get the current OS version and put it in a global variable. And in functions that are version-dependent, this variable can be checked and throw an exception in case of an error.

Then user programs can handle the exception and continue execution if the call to this function is not necessary, or it has an alternative implementation. This ensures portability of the executable between OS versions.

But it should be expected that now a simple API call can return an exception. So it is better to define a global directive (e.g. "WINAPI_CHECKVER") to allow/disable such a check.



2. At compile time

In this case, when compiling, you must first somehow specify a specific version (just as you can now specify a CPU, OS, and widget set in the IDE).

Then, based on this, the path with the required include file can be selected, as suggested by Thaddy (if I understood correctly).

This is a faster way not only for compilation, but also for running (since there are no checks at runtime). However, unlike the first method, it simply prevents the program from compiling at all, whether this function is needed or not.

By the way, this method is quite "officially" feasible, since the MS website always indicates the minimum required version. For example, for VirtualAlloc2, "Windows 10" is clearly written at the bottom. Perhaps someone will even be able to write a program to automatically generate such files.

440bx

  • Hero Member
  • *****
  • Posts: 5137
Re: Warning on identifier usage ?
« Reply #7 on: March 26, 2025, 03:32:47 am »
I would like the feature to be available at compile time and, very important, to be totally independent of a Windows version.

This last part likely requires an explanation.  The MSVC Windows headers are peppered with Windows version checks to include/exclude specific features.  That's convenient but, it isn't what I really want.  Also, it's very easy to implement but, as @Thaddy mentioned, it would be an enormous amount of work to implement now, not to mention that it would likely affect all existing code, which would be extremely undesirable.

What I really want is simpler.  Basically, regardless of the program's Windows target version, to associate a message string with the use of a particular "item".  I used VirtualAlloc2 as an example but, I could have used an enumeration, a constant value or some data type.

Sticking with VirtualAlloc2 as the example.  Anytime the compiler sees that the function VirtualAlloc2 is used, it would output the "onuse" message that is associated with it.  In this case, the message "VirtualAlloc2 requires Windows 10 version 1607 or greater" (but, the message could be anything that the programmer wishes to associate with the "identifier" - VirtualAlloc2 in this example.)

The message would inform the programmer that his/her program will not run on any version of Windows before Windows 10 version 1607.  It would then be up to the programmer to decide if the program should be changed to remove that requirement.  IOW,  _strictly_ informational (unlike what the Windows version checks do in the C headers.)

It's important to realize that, as far as the Windows API is concerned, in the great majority of the cases, the feature would be used to note that a specific version of Windows is associated with the use of the feature but, it could be used for other things.  For instance, imagine you wrote some library of functions and one of the functions is a very attractive/useful feature but, it is very slow.  That function could have an "onuse" message stating "WARNING: function XYZ is slow and consumes a lot of CPU" or "WARNING: function XYZ is slow and consumes a lot of memory" or whatever other important detail the programmer should be aware of about function XYZ.  Note that this makes the feature platform independent, it's not Windows specific nor specific to the version of something or other.

Real cases that come to mind are DrawText and DrawTextEx.  Both of these functions are extremely slow and consume a lot of CPU.  They should only be used very occasionally because using them extensively will  cause the program to be slow and consume a lot of CPU (that's why Windows explorer no longer uses the Listview standard control because that control uses DrawText (or Ex, don't remember.)   Another case, is user32's wsprintf family of functions, they are a performance disaster and in addition to that they are very limited in functionality, essentially those functions are worthless and they should be avoided.  An "onuse" message stating that the reason these functions should be avoided would be very helpful to an uninformed programmer.  (Other "quirks" associated with other Windows functions come to mind which only increases the value of the feature)

In addition to the above, it would be very useful for a programmer who wrote a library of functions to include a particular message about some function when the function is used.  This would be very convenient and provide potentially critical information to a programmer who uses a particular function/feature.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Khrys

  • Full Member
  • ***
  • Posts: 208
Re: Warning on identifier usage ?
« Reply #8 on: March 26, 2025, 07:34:08 am »
This would essentially be  deprecated  with a custom message that isn't constrained to  'Warning: Symbol "<name>" is deprecated: "<message>"'.
Additionally, it should be applicable to variables (specifically function pointers) as well, considering how APIs that could benefit from this kind of documentation are commonly implemented via dynamic libraries (take OpenGL as an example  -  glClearglBindBuffer  etc. are all defined as function pointers).

Certainly useful, but there should be a way to acknowledge/silence these warnings. Personally I make sure that all my code compiles without warnings, and for explicitly ignoring certain warnings I strongly prefer doing it at the compiler level via  {$warn xxxx off}  directives and avoid using  {%H-}  since the latter only applies to Lazarus' output window. I don't think it's feasible (or desirable) to assign identifiers to  onuse  messages for selective silencing, so a globally acting (local) directive akin to  {$WARNINGS OFF}  seems to be the only option.



On a sidenote,  deprecated  currently stays silent when taking the address of a function; I don't think this is intended behavior:

Code: Pascal  [Select][+][-]
  1. procedure Foo(); deprecated 'does nothing';
  2. begin
  3. end;
  4.  
  5. procedure Bar();
  6. var
  7.   Proc: TProcedure;
  8. begin
  9.   Proc := @Foo; // <--- No warning
  10.   Proc();
  11. end;

440bx

  • Hero Member
  • *****
  • Posts: 5137
Re: Warning on identifier usage ?
« Reply #9 on: March 26, 2025, 07:45:57 am »
if "deprecated" didn't state that the symbol is deprecated, it would do what I want. 

All I want is a way to output a message when a symbol is used.  That simple. 

The purpose of the message can vary depending on the symbol.  It may warn/inform the programmer about some version requirement or high memory or cpu usage or anything else that the author considered is important for the programmer who intends to use it (the symbol) to be aware of.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10997
  • Debugger - SynEdit - and more
    • wiki
Re: Warning on identifier usage ?
« Reply #10 on: March 26, 2025, 09:09:55 am »
Just out of curiosity: Is the "deprecated" so bad? If you add that to your definitions, and the compiler outputs it, together with your text (which could start "not deprecated"), then you still would know what it means? And so would anyone with whom you work on this?

On the other hand, I have the feeling that is not the full story of what you want... There must be plenty such API defs in the RTL.
So the big question is, do you want the RTL littered with "on_use" directives? Having every user get those messages?

Because that I would be "not a friend of" (very politely said).



I also wonder, if you want such a message, what reaction do you plan as your response to getting it?

I mean, if you did not want to use the call at all, then don't add it's definition (and get an error, that it isn't known). Or if it is in FPC, then use some form of linter.

But if you do use it, then what is the message for? You eventually get more and more of those messages, knowing that you used the call on purpose?
 

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12142
  • FPC developer.
Re: Warning on identifier usage ?
« Reply #11 on: March 26, 2025, 09:42:49 am »
(i'd use that <symbol,windows version> list that you would try to put into windows into an util that scans the map file and deliver any custom warnings for legacy windows versions purposes)
« Last Edit: March 26, 2025, 10:11:10 am by marcov »

440bx

  • Hero Member
  • *****
  • Posts: 5137
Re: Warning on identifier usage ?
« Reply #12 on: March 26, 2025, 01:45:20 pm »
@Martin,

The presence of "deprecated" is misleading.  That's what I really don't like about using "deprecated".

As far as more to the story, not really.  I see the main purpose of the feature to be a way to issue a strictly informational message to the programmer about his/her program requiring a version of Windows which may not be something the programmer realized, e.g, when using VirtualAlloc2, the program forces the user to run Windows 10 version 1607 or greater which may be an undesirable side effect of using that function.

Yes, the feature can be used for other purposes as well and can easily be abused but, in the case of APIs, that's controlled by the Lazarus/FPC developers, therefore in that area it is very unlikely to be abused.  If it is abused by someone who wrote a library, as long as the library's source code is available, it is trivial to remove the message without any functional side effects whatsoever.

An example of a really bad instance of emitting unnecessary and misleading messages comes from FPC's consideration of "var" implying that the variable has been initialized.  For someone like me who codes directly to the API, that results in a torrent of incorrect, totally worthless messages that get in the way of other messages that may be useful.   Very sadly, the amount of work it takes to eliminate those garbage message is often too large to indulge in it.   N. Wirth _explicitly_ warns the readers in the language report and manual against that very assumption, yet, FPC makes it and the developers refuse to correct it.  Yes, the presence of that thing annoys me because it gets in my way _every_ day and there is nothing I can do about it.  Not only it is extremely annoying, the annoyance never stops, it just accumulates and it often results in a lot extra work to inspect messages that may be useful.  Utterly useless and a gratuitous waste of time.  Of all the bad ideas that found a home in FPC, that might very well be the worst one and, amazingly, it is staunchly protected by the FPC developers... go figure!!

Unlike the "var" thing, any message associated with a symbol can be removed whenever the source is available, something which cannot be done to remove FPC's incorrect handling of "var".  (only way is to modify the compiler.)



@marco,

the problem with that solution is that the map file excludes information.  For instance, there are constants that are available only for a Windows version >= xxxx and those will not present in a map file.  That applies to any symbol that is used in the source that doesn't identify an address in the executable.  Also, map files usually exclude a lot of symbols for one reason or another greatly affecting its usefulness.




"deprecated" is a good example how the feature is useful.  It doesn't depend on some external utility and anything that is deprecated can be marked as such.  Also, it is a way for knowledge about an identifier to accumulate in the definition files.  This last part is very important because important knowledge should not be lost or be present only in the documentation (no one reads the documentation every day nor for every function used.)
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12142
  • FPC developer.
Re: Warning on identifier usage ?
« Reply #13 on: March 26, 2025, 05:15:41 pm »
I don't entering tons of legacy OS info in headers is a good solution for the rare case that somebody is developing complicated new software that must run on unsupported Windows.

My remark must be seen in that light. Not a perfect solution, but an achievable one.

440bx

  • Hero Member
  • *****
  • Posts: 5137
Re: Warning on identifier usage ?
« Reply #14 on: March 26, 2025, 05:27:33 pm »
I don't entering tons of legacy OS info in headers is a good solution for the rare case that somebody is developing complicated new software that must run on unsupported Windows.
The problem isn't really rare.  The .h headers are peppered with conditionals to change a definition to account for a particular Windows version.

The FPC definitions try to be Windows agnostic but, there are a good number of cases where that is not possible, e.g, there are structure layouts that differ from one version of Windows to another and currently, the FPC definitions neither account for that nor provide a good method to inform the programmer that he/she has run into such a case.

Of course, that's a problem for someone like me who programs to the API and is directly affected by those things and, much less for programmers that just use platform independent library code.

It would be very convenient to have a mechanism to inform the programmer of important facts about a function/procedure/record/type/etc, that would help the programmer not get caught in a undesirable situation.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018