Recent

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

Bitbeisser

  • New Member
  • *
  • Posts: 42
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #15 on: November 13, 2025, 12:12:54 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;
You did not read my whole post. As I clearly mentioned that I do not want to get this message where it clearly is wrong, because I explicitly DO initialize a variable on first use, most commonly using either a FillChar() or BlockRead() statement. For all other cases of this warning, I do want to get it, because it indicates something is wrong, like in your example with the ShowMessage (s). THAT is a programming bug (though possibly of varying severity). Or (with a different warning), the not used variables. I DO want to be notified about those.

I will later today make some tests of your {%H-} suggestion, to see what (side)effects that has and it indeed is identical to the {$WARN xxxx OFF} method, however without having to deal with possibly shifting message ID numbers...

Ralf

Bitbeisser

  • New Member
  • *
  • Posts: 42
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #16 on: November 13, 2025, 12:27:32 am »
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").
What is that supposed to do? Beside just obfuscating the code, I would still get that warning when passing the variable to initialize to what you call a "small wrapper". In fact I do get this warning on several calls where I send a structure (record/array) to a specific initialization function, which might fill the array or record members differently, depending on outside circumstances. I work a lot with data exchange/conversion to and from EBCDIC encoded data, and while a space character is $20/20h in ASCII, it is $40/40h in EBCDIC.
Quote
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.
Irrelevant to my problem and the start to get the whole thread off-topic...  :(
Quote
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.
Non-issue, as I do not use the command line compiler, and just not seeing the warning is perfectly fine, as it doesn't change anything how the compiler is generating code. It is just that in cases like FillChar() or a self-written procedure/function/method, the compiler can't decide if the variable is actually initialized or not. And that is fine, I just don't want to bother with those "false positive" warnings and much rather concentrate on other, potentially more serious warnings, indicating a possible mistake/bug...

Ralf

Khrys

  • Sr. Member
  • ****
  • Posts: 364
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #17 on: November 13, 2025, 09:03:36 am »
Use typed or untyped out parameter variables in small wrapper procedures around calls to FillChar (I use "MemClear" and "MemFill").
What is that supposed to do?

From the link:

Quote from: Out parameters (FPC reference guide)
The difference of out parameters and parameters by reference is very small (however, see below for managed types): the former gives the compiler more information about what happens to the arguments when passed to the procedure: it knows that the variable does not have to be initialized prior to the call.

[...]

Remark For managed types (reference counted types), using Out parameters incurs some overhead: the compiler must be sure that the value is correctly initialized (i. e. has a reference count of zero (0)). This initialization is normally done by the caller.

Passing a variable of a managed type (like  AnsiString  or arrays) as the argument of an  out  parameter thus implicitly initializes the variable at the call site:

Code: Pascal  [Select][+][-]
  1. procedure InitByVar(var X: String);
  2. procedure InitByOut(out X: String);
  3.  
  4. // This call...
  5. InitByOut(X);
  6.  
  7. // ...is equivalent to this:
  8. X := '';
  9. InitByVar(X);

Thaddy

  • Hero Member
  • *****
  • Posts: 18475
  • Here stood a man who saw the Elbe and jumped it.
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #18 on: November 13, 2025, 09:17:31 am »
That does not take away from e.g. SetLength() not being recognized as initialization.

But I still wonder why my counter-example indeed does not work: there is a bug when you reverse the logic.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

creaothceann

  • Full Member
  • ***
  • Posts: 220
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #19 on: November 13, 2025, 10:43:55 am »
What is that supposed to do?
No warnings about uninitialized variables.

Code: Pascal  [Select][+][-]
  1. program Test_Warnings;
  2.  
  3.  
  4. var
  5.         f       : file;
  6.         a, b, c : byte;
  7.  
  8.  
  9. procedure FillChar_v2 (               const pData : pointer;  const Size : SizeInt);  inline;  begin  FillChar (    pData^, Size, 0);  end;
  10. procedure BlockRead_v2(var f : file;  const pData : pointer;  const Size : SizeInt);  inline;  begin  BlockRead(f , pData^, Size   );  end;
  11.  
  12.  
  13. begin
  14.         AssignFile(f, 'data.bin');
  15.         Reset(f, 1);
  16.         ;                    BlockRead   ( f,  a, 1);  // 'Variable "a" does not seem to be initialized'
  17.         FillChar_v2(@b, 1);  BlockRead   ( f,  b, 1);  // no warning, wrapper 'FillChar_v2' initializes variable
  18.         ;                    BlockRead_v2( f, @c, 1);  // no warning, wrapper 'BlockRead_v2' reads file
  19.         CloseFile(f);
  20. end.
  21.  

Apparently I was wrong about inlining a function if it has var/out parameters, this only seems to not work with untyped parameters.
Quote from: Thaddy
And don't start an argument, I am right.
Quote from: Thaddy
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)

Thaddy

  • Hero Member
  • *****
  • Posts: 18475
  • Here stood a man who saw the Elbe and jumped it.
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #20 on: November 13, 2025, 12:11:20 pm »
Yes, this time it compiles and is correct..,.. :-X
Keep up the efforts.... ::)
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8515
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #21 on: November 13, 2025, 12:46:36 pm »
I will later today make some tests of your {%H-} suggestion, to see what (side)effects that has and it indeed is identical to the {$WARN xxxx OFF} method, however without having to deal with possibly shifting message ID numbers...

I don't like getting involved in an already-contentious thread, but note that the precise positioning of that depends very much on the type of error: I suggest relying on the Lazarus IDE and the skill of its developers rather than guessing where the marker needs to go.

Apart from that I'm afraid that I'm in no position to apologise for situations where use of the RTL etc. results in a warning.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

PascalDragon

  • Hero Member
  • *****
  • Posts: 6229
  • Compiler Developer
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #22 on: November 13, 2025, 10:31:43 pm »
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.

Just use MyVar := Default(TypeOfVar).

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.

They are not all warnings. Most of them are hints and/or notes.

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>:(

In main the number of generated warnings at least by the TDictionary class have been reduced.

That does not take away from e.g. SetLength() not being recognized as initialization.

Because it isn't:

Code: Pascal  [Select][+][-]
  1. program tarrresult;
  2.  
  3. {$mode objfpc}
  4.  
  5. type
  6.   TArrayLongInt = array of LongInt;
  7.  
  8. function Test1: TArrayLongInt;
  9. begin
  10.   Result := [1, 2, 3];
  11. end;
  12.  
  13. function Test2: TArrayLongInt;
  14. begin
  15.   SetLength(Result, 2);
  16. end;
  17.  
  18. var
  19.   l: TArrayLongInt;
  20.   i: LongInt;
  21. begin
  22.   l := Test1;
  23.   l := Test2;
  24.   for i in l do
  25.     Writeln(i);
  26. end.

Code: [Select]
PS C:\fpc\git> .\testoutput\tarrresult.exe
1
2

Bitbeisser

  • New Member
  • *
  • Posts: 42
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #23 on: November 13, 2025, 10:45:31 pm »
What is that supposed to do?
No warnings about uninitialized variables.
That's what is easily achieved with temporarily turning off the warning for specific functions, without generating any additional code or obfuscating the source code in the first place.

Bitbeisser

  • New Member
  • *
  • Posts: 42
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #24 on: November 13, 2025, 10:56:02 pm »
Passing a variable of a managed type (like  AnsiString  or arrays) as the argument of an  out  parameter thus implicitly initializes the variable at the call site:

Code: Pascal  [Select][+][-]
  1. procedure InitByVar(var X: String);
  2. procedure InitByOut(out X: String);
  3.  
  4. // This call...
  5. InitByOut(X);
  6.  
  7. // ...is equivalent to this:
  8. X := '';
  9. InitByVar(X);
Well, it is quite obvious that "initializing" means different things to different people. As I tried to explain, the initialization in a lot of cases that I intentionally do with using FillChar() or a specific procedure/function/method, when different elements of a structure need to get different initial values, is flagged as using an "uninitialized" variable, which simply is unnecessary. And your default initialization isn't helping, as I have a lot of cases where "default initialization" of an array/string/record can differ depending on what the target encoding is. It might not be obvious for a lot of whippersnappers, but ASCII and EBCDIC, for example, are quite different. And your example might work for a simple (ASCII) string, but not for any more complex data structure...
Again, having the right message ID to temporarily turn the warning off for a specific line works just fine, the problem seems to have been that this message ID over time might have shifted...

Bitbeisser

  • New Member
  • *
  • Posts: 42
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #25 on: November 13, 2025, 11:01:46 pm »
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.

Just use MyVar := Default(TypeOfVar).

In most non-trivial applications, this just might simply not work, as it assumes that this is a local variable that gets initialized "once", and as I mentioned elsewhere already, twice, such a "default" by the compiler might simply not be what the application needs at runtime...

Khrys

  • Sr. Member
  • ****
  • Posts: 364
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #26 on: November 14, 2025, 07:38:45 am »
Well, it is quite obvious that "initializing" means different things to different people.

The only meaning of "initialization" that matters is that of the compiler. You need to explicitly assign a value to local variables (by means of  :=  or  out)  or they'll contain garbage from the stack and the compiler will rightfully complain.

Just use MyVar := Default(TypeOfVar).
In most non-trivial applications, this just might simply not work, as it assumes that this is a local variable that gets initialized "once", and as I mentioned elsewhere already, twice, such a "default" by the compiler might simply not be what the application needs at runtime...

This is equivalent to  FillChar(MyVar, SizeOf(MyVar), 0)  but won't emit any warnings since it is an actual assignment.

And your default initialization isn't helping, as I have a lot of cases where "default initialization" of an array/string/record can differ depending on what the target encoding is. It might not be obvious for a lot of whippersnappers, but ASCII and EBCDIC, for example, are quite different. And your example might work for a simple (ASCII) string, but not for any more complex data structure...

I gave an example on the documentation of  out  parameters (which you obviously didn't read) and that's it. I didn't tell you to initialize your EBCDIC strings (or whatever) that way. Apart from that, default initialization of an array or string will never differ depending on the target encoding because default-initialized instances of those types are empty. Pray tell me, what's the encoding of this string: '' ?

Now I wonder what witchcraft your "initialization" code performs. Quoting @Thaddy:

Can you provide an example this time? I doubt it. (because you never do out of incompentence)

Thaddy

  • Hero Member
  • *****
  • Posts: 18475
  • Here stood a man who saw the Elbe and jumped it.
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #27 on: November 14, 2025, 10:37:03 am »
Yeah, I should not have sarcastic mode on all the time, but the most valuable contributions to this forum are the ones with compilable examples. Well, actually, that includes examples that should compile but do not.
Otherwise it looks like opinions and we all know about those....
My only excuse is I am Dutch. It's genetic in the region I was born: Amsterdam.(The same as the NY affected Dutch heritage, but we can even teach those about what arrogance should look like)

So somewhat complete examples would help: I replied to another question by repeating correct code from somebody else and from 13 years ago.

I have no manners - and do not intend to change that-, but plz: when you want help and you want people to help you at least make an effort to describe your problem in some way that can be repeated/replicated.

Otherwise it would be a waste of time.
« Last Edit: November 14, 2025, 11:05:01 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Thaddy

  • Hero Member
  • *****
  • Posts: 18475
  • Here stood a man who saw the Elbe and jumped it.
Re: Variable "xyz" doesn't not seem to be initialized (again/still) :(
« Reply #28 on: November 14, 2025, 11:17:25 am »
What I’d really like is a way to suppress the warning only in those specific cases, while keeping it active elsewhere. That way I can focus on meaningful warnings — unused variables, genuinely uninitialized managed types — instead of being distracted by noise.
The problem is, that the {$push}/{pop} seems not to obey in all cases.
And that means the intention is there. There is a bug.
« Last Edit: November 14, 2025, 11:22:12 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

creaothceann

  • Full Member
  • ***
  • Posts: 220
Quote from: Thaddy
And don't start an argument, I am right.
Quote from: Thaddy
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)

 

TinyPortal © 2005-2018