Recent

Author Topic: Apparently uninitialized variable.....  (Read 3676 times)

Prime

  • Jr. Member
  • **
  • Posts: 67
Apparently uninitialized variable.....
« on: January 08, 2025, 11:03:03 pm »
Hi all,

If I have something like :
Code: [Select]

Type
  TRecordType = record
    Field1 : INTEGER;
Field2 : BYTE;
  end;

Procedure DoSomething(     InputData : TMemoryStream;
                      OUT OutputData : TRecordType);
       
begin
  InputData.Read(OutputData,Sizeof(OutputData));
end;

I get an warning that OutputData does not seem to be initialized. For simple variables, I can just assign them a default value in the VAR section but that won't easily work here.
Is there a good way to solve this, or should I just accept that the warning is going to be there :)

Cheers.

Phill.

440bx

  • Hero Member
  • *****
  • Posts: 6017
Re: Apparently uninitialized variable.....
« Reply #1 on: January 09, 2025, 01:10:15 am »
Is there a good way to solve this, or should I just accept that the warning is going to be there :)
I wouldn't call it "good" but, if you assign a value to either Field1 or Field2 of OutputData, that will get rid of the hint.

You could make the assignment conditional by making it conditional to a {$define NO_UNINITIALIZED_HINTS} which could be undefined for the release version so no code is generated for all superfluous initializations.  To save some typing (and time) you  could create a template for it.

the code would look like something like this (except that the $define would likely be in a place where it is global, not in a procedure):
Code: Pascal  [Select][+][-]
  1.   { the define somewhere where it is global }
  2.  
  3.   {$define NO_UNINITIALIZED_HINTS}  { defined here only for example's sake }
  4.  
  5.   Procedure DoSomething(     InputData : tmemorystream;
  6.                         OUT OutputData : TRecordType);
  7.   begin
  8.     {$if defined(NO_UNINITIALIZED_HINTS)} OutputData.Field1 := 1; {$endif}
  9.  
  10.     InputData.Read(OutputData,Sizeof(OutputData));
  11.   end;
  12.  

No matter what, it's inconvenient.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

jamie

  • Hero Member
  • *****
  • Posts: 7486
Re: Apparently uninitialized variable.....
« Reply #2 on: January 09, 2025, 01:33:04 am »
or
I believe you can use {&H-} or was it {%H-} just after the out variable which should suppress it.

Jamie

The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 18676
  • Jungle wars. And failing health it seems.
Re: Apparently uninitialized variable.....
« Reply #3 on: January 09, 2025, 02:24:53 am »
{$hints off} or {$warn <number> off}
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

robert rozee

  • Sr. Member
  • ****
  • Posts: 282
Re: Apparently uninitialized variable.....
« Reply #4 on: January 09, 2025, 07:21:01 am »
this should do the trick if placed before you try the read operation:
fillchar(outputdata, sizeof(outputdata), #0);

or better still:
try
  InputData.Read(OutputData,Sizeof(OutputData))
except
  fillchar(outputdata, sizeof(outputdata), #0)
end;


in your original code, if the read operation fails then the contents of outputdata is unaltered from what it was when the procedure is entered. it is this possibility that the compiler is warning you about.

for extra points, change your procedure into a function and set result:=true after the read succeeds, and  result:=false after the fillchar. this means the calling code can tell if anything went wrong.


cheers,
rob   :-)

Thaddy

  • Hero Member
  • *****
  • Posts: 18676
  • Jungle wars. And failing health it seems.
Re: Apparently uninitialized variable.....
« Reply #5 on: January 09, 2025, 07:32:19 am »
Call default on the variable that receives outputdata before you call the procedure.(not inside the procedure)
Code: Pascal  [Select][+][-]
  1. OutputData := default(TRecordType);
« Last Edit: January 09, 2025, 07:37:44 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

robert rozee

  • Sr. Member
  • ****
  • Posts: 282
Re: Apparently uninitialized variable.....
« Reply #6 on: January 09, 2025, 08:00:45 am »
Call default on the variable that receives outputdata before you call the procedure.(not inside the procedure)
Code: Pascal  [Select][+][-]
  1. OutputData := default(TRecordType);

default() produces exactly the same result as fillchar(..., #0). see:
https://gitlab.com/freepascal.org/fpc/source/-/issues/34972
although, depending on the implementation, default may briefly consume a  sizeof(TRecordType) sized block of memory in which to create the 'default' record, then have to spend time copying from said memory block into Outputdata.

i don't see any harm in doing the initialization within the op's procedure/function. i do see value in the procedure/function passing out a flag in some way to indicate a read failure.


cheers,
rob   :-)

Thaddy

  • Hero Member
  • *****
  • Posts: 18676
  • Jungle wars. And failing health it seems.
Re: Apparently uninitialized variable.....
« Reply #7 on: January 09, 2025, 08:35:40 am »
I know that in this case fillchar does the same, however I use default() wherever possible. Mainly to prevent err on managed types. It is not always the case that just fillchar() can be used, contrary to default() that always can be used.
side note:both fillchar with zero's and default() can cause range issues.
That is the case if the range can not contain zero. In that case fillchar() with the lowest possible value in the range is probably the better option.
« Last Edit: January 09, 2025, 08:47:29 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

 

TinyPortal © 2005-2018