Recent

Author Topic: Variable "xyz" doesn't not seem to be initialized (again/still) :(  (Read 2553 times)

Bitbeisser

  • New Member
  • *
  • Posts: 42
I did look through the forum for a solution for my problem. I keep getting a lot of those"variable xyz doesn't seem to be initialized" warnings, which is rather a nuisance, possibly blending out real, more important warning messages, especially on larger project builds.

The most common cases are either calls to standard functions like FillChar() or BlockRead() at the beginning of a function/procedure, for the explicit purpose of "initializing" the variable in the parameter of those two functions. Or passing an array/record variable to a self-written procedure like InitializeStructure (MyRecord), likewise for the explicit purpose of initializing the passed variable.
There are quite a number of (older) forum posts about this, with the most common recommendation to use one or another version of a {$WARN nnnn oFF} {$WARN ON} around the affected line of source code (with or without PUSH/POP), but none of those seem to be working anymore.

And to be clear, I do not want to generally disable these warnings, as there might be very well lines where this is indeed a valid warning, maybe due to a typo or such. Those, in fact, I DO WANT to see, so to fix the code. And no, I do not want to plaster "dummy" initialization statements all over my source code either. This just should not be necessary. Just a way to selectively, temporarily disable those warnings...

Ralf
« Last Edit: November 12, 2025, 01:28:41 am by Bitbeisser »

dsiders

  • Hero Member
  • *****
  • Posts: 1497
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #1 on: November 12, 2025, 02:08:14 am »
...the most common recommendation to use one or another version of a {$WARN nnnn oFF} {$WARN ON} around the affected line of source code (with or without PUSH/POP), but none of those seem to be working anymore.

That's certainly not my experience using the Lazarus IDE.

You can specify options at project level to control hints, warnings, and notes. Project Options > Compiler Options > Messages. You can also force those to be the compiler defaults.  See attached image.

You can Right click on any message in the Messages window to add or remove filter, or even create you own custom set of filters for the messages.

Multiple options... pick one.

If you're not using Lazarus, then you need to learn the command line options to pass to the compiler. https://www.freepascal.org/docs-html/user/usersu13.html#x36-430005.1.2
« Last Edit: November 12, 2025, 02:10:37 am by dsiders »
Preview the next Lazarus documentation release at: https://dsiders.gitlab.io/lazdocsnext

Bitbeisser

  • New Member
  • *
  • Posts: 42
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #2 on: November 12, 2025, 02:28:15 am »
Quote
You can specify options at project level to control hints, warnings, and notes. Project Options > Compiler Options > Messages. You can also force those to be the compiler defaults.  See attached image.
As I stated, I do NOT want to disable it per unit/project, as that would/could result in hiding legitimate cases of this type of warnings. I just want it deliberately disable for specific statements, where I know that the variable will  never be used uninitialized...
Quote
You can Right click on any message in the Messages window to add or remove filter, or even create you own custom set of filters for the messages.

Multiple options... pick one.
Well, just like your first suggestion, it inserts the {$WARN 5068 OFF} at the top of the unit/program file, effecting the whole file and this is NOT what I want.

I noticed when I followed your second suggestion, it referred to warning 5058, while in the past this used to work when using localized PUSH/WARN nnnn OFF/WARN nnnn ON/POP around the "offending" lines, this used to work, at some point in the past with message numbers 5057, 5080, 5091 and/or 5036. So there seem to be some shift probably between FPC versions, which isn't very helpful unfortunately... :( :(

Handoko

  • Hero Member
  • *****
  • Posts: 5507
  • My goal: build my own game engine using Lazarus
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #3 on: November 12, 2025, 03:05:25 am »
I'm with Bitbeisser. Lazarus IDE would be perfect to me if it doesn't have this issue. But I can tolerate with this small nuisance, I do not turn off the warnings.

Bitbeisser

  • New Member
  • *
  • Posts: 42
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #4 on: November 12, 2025, 03:53:02 am »
I'm with Bitbeisser. Lazarus IDE would be perfect to me if it didn't have this issue. But I can tolerate this small nuisance, I do not turn off the warnings.
It might not be a problem for a small program, but what I recently tried to recompile is a rather large application with about 3 dozen units and close to 100,000 lines of code. That resulted in A LOT of those warnings.
Right now, with using {$WARN 5058 OFF}, this is solved for this particular application, as it was a couple (3?) years ago, roughly, the last time that I built the whole application, back then with an older Lazarus and FPC version.
But what I would like to see is a more standardized way that doesn't rely on floating error message numbers that need to be adjusted in the {$WARN} text throughout the source code...

Thaddy

  • Hero Member
  • *****
  • Posts: 18529
  • Here stood a man who saw the Elbe and jumped it.
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #5 on: November 12, 2025, 05:55:29 am »
I noticed when I followed your second suggestion, it referred to warning 5058, while in the past this used to work when using localized PUSH/WARN nnnn OFF/WARN nnnn ON/POP around the "offending" lines, this used to work, at some point in the past with message numbers 5057, 5080, 5091 and/or 5036. So there seem to be some shift probably between FPC versions, which isn't very helpful unfortunately... :( :(
{$push}{$warn 5058 off}....{$pop} still works. Do you have a small example where this would fail? Because that would be a huge bug.
I use the technique daily (and wrote much of the wiki entry that covers it)
It is supposed to override any other method of turning the warning on or off, even the commandline -vw5058-/+
If it is in the sourcecode itself, the message should be gone, whatever other methods are used and that includes the Lazarus IDE.
« Last Edit: November 12, 2025, 06:07:02 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

paweld

  • Hero Member
  • *****
  • Posts: 1525
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #6 on: November 12, 2025, 07:13:26 am »
If you use Lazarus, you can use the IDE directive: {%H-}, which hides hints for specific code.
For example, for the code:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   s: String;
  4.   i: Integer;
  5. begin
  6.   ShowMessage(s);
  7. end;
you will receive the following hints/warnings
Code: [Select]
unit1.pas(4,3) Note: Local variable "i" not use
unit1.pas(6,16) Warning: Local variable "s" of a managed type does not seem to be initialized

Inserting the directive before the variable definition i will cause the hint about the unused variable to disappear:
Code: Text  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   s: String;
  4.   {%H-}i: Integer;
  5. begin
  6.   ShowMessage(s);
  7. end;
To completely clear the hints, you must also use the directive where the variable s is used, which means that the code below will not generate any hints:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   s: String;
  4.   {%H-}i: Integer;
  5. begin
  6.   ShowMessage({%H-}s);
  7. end;
Best regards / Pozdrawiam
paweld

creaothceann

  • Full Member
  • ***
  • Posts: 223
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #7 on: November 12, 2025, 08:05:26 am »
I keep getting a lot of those"variable xyz doesn't seem to be initialized" warnings, which is rather a nuisance, possibly blending out real, more important warning messages, especially on larger project builds.
Agreed. Whenever I recompile the IDE it surprises me how many warnings are dumped into the Messages window - ideally there should be none.


The most common cases are either calls to standard functions like FillChar() or BlockRead() at the beginning of a function/procedure, for the explicit purpose of "initializing" the variable in the parameter of those two functions. Or passing an array/record variable to a self-written procedure like InitializeStructure (MyRecord), likewise for the explicit purpose of initializing the passed variable.
Use typed or untyped out parameter variables in small wrapper procedures around calls to FillChar (I use "MemClear" and "MemFill").

If you want to use the inline keyword on these procedures/functions you should use a (const) pointer instead (because procedures/functions with var/out parameters still can't be inlined). In that case you don't even have to disable any warnings.
(EDIT: apparently, functions with var parameters can be inlined.)


If you use Lazarus, you can use the IDE directive: {%H-}, which hides hints for specific code
Wiki: "Note that this turns off ALL hints for that parameter, not just the 'is not used' hint, so be careful."

And afaik these warnings are still generated, but are filtered out of the message window. Which seems like a bandaid solution, and sucks for people who are compiling via the command-line.
« Last Edit: November 13, 2025, 01:52:30 pm by creaothceann »

Khrys

  • Sr. Member
  • ****
  • Posts: 367
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #8 on: November 12, 2025, 08:14:23 am »
Another thing I find very annoying is that it's impossible to selectively silence notes/warnings from generics in other units.
I have a package that by itself would compile without warnings, but it uses  TDictionary  from  Generics.Collections,  meaning that my message window is cluttered with 11 to 14 distracting messages per specialization>:(

Quote from: text
generics.collections.pas(1186,20)   Note: Call to subroutine "function TEnumerable<System.LongInt>.GetEnumerator:TEnumerator$1<SYSTEM.LongInt>;" marked as inline is not inlined
generics.collections.pas(1186,20)   Note: Call to subroutine "function TEnumerable<ExampleUnit.TSomething>.GetEnumerator:TEnumerator$1<ExampleUnit.TSomething>;" marked as inline is not inlined
generics.collections.pas(1186,20)   Note: Call to subroutine "function TEnumerable<ExampleUnit.TPair<System.LongInt,ExampleUnit.TSomething>>.GetEnumerator:TEnumerator$1<ExampleUnit.TPair$2<SYSTEM.LongInt,ExampleUnit.TSomething>>;" marked as inline is not inlined
generics.dictionaries.inc(191,92)   Warning: Constructing a class "TCustomDictionaryEnumerator$4$crc13AE9607" with abstract method "DoMoveNext"
generics.collections.pas(121,14)    Hint: Found abstract method: DoMoveNext(<TEnumerator$1$crc4E1B6E1D>):Boolean;
generics.dictionaries.inc(191,92)   Warning: Constructing a class "TCustomDictionaryEnumerator$4$crc13AE9607" with abstract method "GetCurrent"
generics.dictionariesh.inc(119,14)  Hint: Found abstract method: GetCurrent(<TCustomDictionaryEnumerator$4$crc13AE9607>;<var TSomething>):<record type>;
generics.dictionaries.inc(191,92)   Warning: Constructing a class "TCustomDictionaryEnumerator$4$crcD7C70F30" with abstract method "DoMoveNext"
generics.collections.pas(121,14)    Hint: Found abstract method: DoMoveNext(<TEnumerator$1$crc9F312717>):Boolean;
generics.dictionaries.inc(191,92)   Warning: Constructing a class "TCustomDictionaryEnumerator$4$crcD7C70F30" with abstract method "GetCurrent"
generics.dictionariesh.inc(119,14)  Hint: Found abstract method: GetCurrent(<TCustomDictionaryEnumerator$4$crcD7C70F30>):LongInt;
generics.collections.pas(144,52)    Note: Private type "TCustomPointersEnumerator$2<SYSTEM.LongInt,ExampleUnit.TCustomList$1$crc9F312717.PT>.T" never used
generics.collections.pas(144,52)    Note: Private type "TCustomPointersEnumerator$2<ExampleUnit.TSomething,ExampleUnit.TCustomList$1$crc4E1B6E1D.PT>.T" never used
generics.collections.pas(144,52)    Note: Private type "TCustomPointersEnumerator$2<ExampleUnit.TPair$2<SYSTEM.LongInt,ExampleUnit.TSomething>,ExampleUnit.TCustomList$1$crcFB52A87D.PT>.T" never used

Thaddy

  • Hero Member
  • *****
  • Posts: 18529
  • Here stood a man who saw the Elbe and jumped it.
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #9 on: November 12, 2025, 08:27:12 am »
You have a thorough misunderstanding of what I wrote.
Can you provide an example this time? I doubt it. (because you never do out of incompentence)
I just checked:
It still works as advertised:
A local direction overrides all other other options.
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. // shows three hints:
  3. // 5024: parameter a not used
  4. // 5024: parameter b not used
  5. // 5028: local proc testme1 not used
  6. procedure testme1(const a,b:integer);
  7. begin
  8. end;
  9. begin
  10. end.
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. // shows only 5028:
  3. procedure testme1(const a,b:integer);
  4. {$push}{$warn 5024 off}
  5. begin
  6. end;
  7. {$pop}
  8. begin
  9. end.
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. // shows none
  3. procedure testme1(const a,b:integer);
  4. {$push}{$warn 5024 off}
  5. begin
  6. end;
  7. {$pop}
  8. {$push}{$warn 5028 off}
  9. begin
  10. end.
  11. {$pop}
Now try from the commandline with -vw5024,5028+ That might expect you to think that you turned them on globally, but is ignored.
And that is exactly what you want.



« Last Edit: November 12, 2025, 08:33:16 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Thaddy

  • Hero Member
  • *****
  • Posts: 18529
  • Here stood a man who saw the Elbe and jumped it.
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #10 on: November 12, 2025, 08:28:12 am »
Another thing I find very annoying
Well, you must be doing something wrong. Posts crossed.
Tested 3.0.4 -with Maciej's repository- , 3.2.3 and 3.3.1.

So unless the Lazarus IDE parses them in violation of the compiler... there is no issue.

I tested with Geany on Windows and Linux. Unit level or program level does not matter.
Suppressing the messages in sourcecode has precedence over everything else.

In your case you can build the affected libraries separate and supress the hints/warnings that offend you too much.
Note that especially in library code, the hints show up correctly - because they are true - but you can supress them.
Code: Text  [Select][+][-]
  1. make clean all install <other install options and paths> OPT=-vw5024,5028,6068-  // any message you don't want....
Code: Text  [Select][+][-]
  1.  11%] Compiled package fcl-xml
  2. Start compiling package rtl-generics for target x86_64-linux.
  3.        Compiling rtl-generics/units/x86_64-linux/BuildUnit_rtl_generics.pp
  4.        Compiling ./rtl-generics/src/generics.collections.pas
  5.        Compiling ./rtl-generics/src/generics.memoryexpanders.pas
  6.        Compiling ./rtl-generics/src/generics.defaults.pas
  7.        Compiling ./rtl-generics/src/generics.hashes.pas
  8.        Compiling ./rtl-generics/src/generics.strings.pas
  9.        Compiling ./rtl-generics/src/generics.helpers.pas
  10. [ 12%] Compiled package rtl-generics
Job done....<sigh>
The messages won't come back...
Try after that:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. uses generics.collections;
  3. type TIntList = TList<integer>;
  4. var
  5.   List:TIntlist;
  6. begin
  7.   List := TIntList.Create;
  8.   List.Free;
  9. end.
Can even compile with -B option, the libraries are compiled such that the messages are not mentioned.
Code: Text  [Select][+][-]
  1. $ fpc -vwlhqn -B tst.pas
  2. Hint: (11030) Start of reading config file /home/thaddy/.fpc.cfg
  3. Hint: (11031) End of reading config file /home/thaddy/.fpc.cfg
  4. Free Pascal Compiler version 3.3.1 [2025/11/10] for x86_64
  5. Copyright (c) 1993-2025 by Florian Klaempfl and others
  6. (1002) Target OS: Linux for x86-64
  7. (3104) Compiling tst.pas
  8. PROGRAM:2 270/384 Kb Used
  9. (9015) Linking tst
  10. (1008) 9 lines compiled, 2.7 sec, 1007712 bytes code, 536832 bytes data

ALL this is documented, so what's the problem? >:(

(Used a fresh compiler build from 10 minutes ago, used also -vh- and -vn- to build fpc complete with all libraries, note the compiler itself is always clean, because of -Sew as default)
« Last Edit: November 12, 2025, 09:28:15 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Khrys

  • Sr. Member
  • ****
  • Posts: 367
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #11 on: November 12, 2025, 10:10:49 am »
In your case you can build the affected libraries separate and supress the hints/warnings that offend you too much.
Note that especially in library code, the hints show up correctly - because they are true - but you can supress them.
Code: Text  [Select][+][-]
  1. make clean all install <other install options and paths> OPT=-vw5024,5028,6068-  // any message you don't want....

You did not understand my post (emphasis added):

Another thing I find very annoying is that it's impossible to selectively silence notes/warnings from generics in other units.

I want my package to compile without warnings, but the warnings from another unit from outside my package (in this case  Generics.Collections) are impossible to selectively silence:
  • Global switches like  -vw5028  are not selective - I want warnings to show up for my code so I can fix them, not suppress all warnings altogether.
  • I can only insert  {$warn xxxx off}  directives into my own code, but the warnings do not originate from my code - they stem from generics being specialized in my code but are (like you pointed out, technically correctly) reported as coming from the unit where they are defined.


Here's a challenge for you:
Given a generic library unit  (Lib.pas)  and a program  (Prog.pas)  that both emit a "private type never used" note, find a way to silence the only the warning from  Lib.pas  when compiling  Prog.pas  using  `fpc Prog.pas`:

Code: Text  [Select][+][-]
  1. Compiling Prog.pas
  2. Lib.pas(9,3) Note: Private type "TFoo$1<SYSTEM.Boolean>.T" never used
  3. Lib.pas(10,19) Note: Private type "TFoo$1<SYSTEM.Boolean>.TEnumerator" never used   <--- Silence
  4. Prog.pas(13,19) Note: Private type "TBar.TEnumerator" never used                    <--- Keep

Code: Pascal  [Select][+][-]
  1. unit Lib;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. type
  8.   generic TFoo<T> = class
  9.   private type
  10.     TEnumerator = class end;
  11.   end;
  12.  
  13. implementation
  14.  
  15. end.

Code: Pascal  [Select][+][-]
  1. program Prog;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Lib;
  7.  
  8. type
  9.   TFooBoolean = specialize TFoo<Boolean>;
  10.  
  11.   TBar = class
  12.   private type
  13.     TEnumerator = class end;
  14.   end;
  15.  
  16. begin
  17. end.

Thaddy

  • Hero Member
  • *****
  • Posts: 18529
  • Here stood a man who saw the Elbe and jumped it.
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #12 on: November 12, 2025, 10:15:56 am »
I want my package to compile without warnings, but the warnings from another unit from outside my package (in this case  Generics.Collections) are impossible to selectively silence:
Khrys, that's why I build the compiler and the rtl and the packages, just to show you:
I do not get any messages from the rtl and packages if build with my options.
I understood your question perfectly correct.
I  showed you the steps.
I would get the messages in my last example, but I did not: because they are not there...
Code: Pascal  [Select][+][-]
  1. unit Lib;
  2. {$mode objfpc}{$H+}
  3. {$warn 5071 off}
  4. interface
  5.  
  6. type
  7.   generic TFoo<T> = class
  8.   private type
  9.     TEnumerator = class end;
  10.   end;
  11. implementation
  12.  
  13. end.
This has unit scope.
Now:
Code: Pascal  [Select][+][-]
  1. unit Lib;
  2. {$mode objfpc}{$H+}
  3. {$warn 5071 off}
  4. interface
  5.  
  6. type
  7. {$push}{$hint 5071 on}
  8.   generic TFoo<T> = class
  9.   private type
  10.     TEnumerator = class end;
  11.   end;
  12. {$pop}
  13. implementation
  14.  
  15. end.
Has local scope...


Note there may verywell be a bug, but I can't replicate it.
Interesting..
« Last Edit: November 12, 2025, 10:29:25 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Thaddy

  • Hero Member
  • *****
  • Posts: 18529
  • Here stood a man who saw the Elbe and jumped it.
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #13 on: November 12, 2025, 10:37:26 am »
Yes I can if I reverse the logic, but that has nothing to do with the rtl-generics (ppu generated) code:
Code: Pascal  [Select][+][-]
  1. unit Lib;
  2. {$mode objfpc}{$H+}
  3. {$warn 5071 on}
  4. interface
  5. {$push}{$warn 5071 off}
  6. type
  7.   generic TFoo<T> = class
  8.   private type
  9.     TEnumerator = class end;
  10.   end;
  11. {$pop}
  12. implementation
  13. end.
That seems like a bug, indeed, because both sides should work.
But the rtl-generics example you gave is not valid, provided my steps. I re-checked.
That is, unless the sourcecode of the rtl-generics is in your path.
« Last Edit: November 12, 2025, 10:40:53 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Bitbeisser

  • New Member
  • *
  • Posts: 42
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #14 on: November 13, 2025, 12:03:49 am »
I noticed when I followed your second suggestion, it referred to warning 5058, while in the past this used to work when using localized PUSH/WARN nnnn OFF/WARN nnnn ON/POP around the "offending" lines, this used to work, at some point in the past with message numbers 5057, 5080, 5091 and/or 5036. So there seem to be some shift probably between FPC versions, which isn't very helpful unfortunately... :( :(
{$push}{$warn 5058 off}....{$pop} still works. Do you have a small example where this would fail? Because that would be a huge bug.
Well, thanks, it is working NOW! As I mentioned, in an older, fairly large project, that hadn't been touched for about 3 years or so (and about 100,000 lines of code, in about 3 dozen units), this used to work using message ID 5057, which failed when recompiling/building the project with the latest Lazarus 4.4 (and still an older FPC 3.2.2) the other days...
Quote
I use the technique daily (and wrote much of the wiki entry that covers it)
Well, that must be a different wiki entry than the one that I am/was aware off, because that one is/was rather non-specific about the message ID to use (and suggesting scrapping over the message file in the compiler install)

It seemed to work when disabling the message in the projects settings (usually do not use plain command line compiles, that's what IDEs are for), but that it exactly what I do NOT want. I just wanted to use it for a (number of) specific line(s)/statement(s)...

It seems that in the past, the message ID used for this warning was different, possibly at some point (Lazarus 3 to Lazarus 4?) shifted from 5057 (which I had all over the mentioned project source code) to 5058, which is working now.

Ralf

 

TinyPortal © 2005-2018