Lazarus

Programming => General => Topic started by: Schmitty2005 on January 24, 2025, 12:58:51 am

Title: Result not being set in class method.
Post by: Schmitty2005 on January 24, 2025, 12:58:51 am
I have a simple method for a class :

Code: Pascal  [Select][+][-]
  1. function TGuitarChordBoxCoOrds.getFretMarkerPoint(gString : Integer; gFret : Integer ):Tpoint;
  2. //@TODO Possible bug function ?
  3. //as a possible workaround use a procedure with a VAR instead!
  4. var
  5.   output : Tpoint;
  6. begin
  7.   output := aFingerPoints[gString, gFret];
  8.   result := output;
  9. end;

for some reason, result does not change to output!  Output is set to the correct values.  Result does not equal output.  Result is another variable used elsewhere, as thought the array pointer is off on the wrong address ?

I think it is ok to use Records as return variables.  Maybe not ?

I tried a simplified test class with a similar function, and it worked as expected.  However, my method in this class does not work ?

What would cause the variable 'output' to be correct, but result with not be set to output ?

Is it best just to use Procedure with VAR  for all class methods ?

FYI aFingerPoints is array [1..6,1..4] of Tpoint
Title: Re: Result not being set in class method.
Post by: ASerge on January 24, 2025, 01:37:27 am
for some reason, result does not change to output!  Output is set to the correct values.  Result does not equal output.  Result is another variable used elsewhere, as thought the array pointer is off on the wrong address ?
We need more code. It is error-free and works properly.
Title: Re: Result not being set in class method.
Post by: Schmitty2005 on January 24, 2025, 01:59:06 am
https://github.com/Schmitty2005/GuitarChordBox (https://github.com/Schmitty2005/GuitarChordBox)

Here is the whole project it is obviously a work in progress.  The breakpoint is set and then a couple of steps into the trouble area.

Thank you.
Title: Re: Result not being set in class method.
Post by: Martin_fr on January 24, 2025, 01:59:26 am
for some reason, result does not change to output!  Output is set to the correct values.  Result does not equal output.

How have you tested this?

If you debugged your app in the debugger, then make sure you use -O- (all optimizations turned off).
Otherwise, the compiled code may "hide" some info from the debugger (i.e. it may set result in such a way that the debugger can not see it).

Also check which debugger is configured.


"the debugger can not see it" => well it could. But the compiler may have told the debugger to look in the wrong place. So it will not see it.

Mind, with -O1 this is very rare to occur. But it can occasionally. Especially (but not limited to) if result is only needed for the one last line of the procedure.
Title: Re: Result not being set in class method.
Post by: Schmitty2005 on January 24, 2025, 02:39:03 am
Dwarf 3 debugger.  I was hovering over variables to get values in IDE during a pause.  It never showed the correct values for this specific method.  All other methods worked fine.

Using -0-, this code compiles and works and the values show as expected.  Thank you!

Will this still happen when using trunk or 3.2 fixes ?  I am currently 3.2.2 ubuntu release. With Lazarus trunk.

Title: Re: Result not being set in class method.
Post by: Martin_fr on January 24, 2025, 09:51:09 am
Using -0-, this code compiles and works and the values show as expected.  Thank you!

Ok, so then if it does not work with optimization that makes it complicated.

Because, the error may or may not be where you think it is.

With optimization, the debugger may show the wrong value, and the error may be somewhere else.
Best chance you hove to check this, is to step out, and check the variable to which the return value is assigned.



If the debugger does show it wrong (but it actually does the right thing), that is probably still being the case in newer fpc versions.

This is because values are stored in temporary places (correct), but the compiler does not undergo the extra work to tell the debugger where those are.



If the value itself is actually wrong, when compiled with optimization.... If the program behaves incorrectly and when stepped out gets the wrong value...

There are several possibilities.

It could be an error, such as an uninitialized value somewhere in your code. However given that "output" was correct, that seems very very unlikely.

It could be a bug in the optimizer. There have indeed been one or two in 3.2.2. They should be fixed in the fixes branch. So if you use FpcUpDeluxe to get that (3.2.3) then that should do.

To know for sure, it would be necessary to compile with -alr, and look at the generated assembler. I have not downloaded your app to check, did not have the time.
Title: Re: Result not being set in class method.
Post by: BrunoK on January 24, 2025, 11:25:22 am
Looking at assembler, in O1, the lines are compiled like if the code was :
Code: Pascal  [Select][+][-]
  1. function TGuitarChordBoxCoOrds.getFretMarkerPoint(gString : Integer; gFret : Integer ):Tpoint;
  2. //@TODO Possible bug function ?
  3. //as a possible workaround use a procedure with a VAR instead!
  4. var
  5.   output : Tpoint;
  6. begin
  7.   result := aFingerPoints[gString, gFret];
  8. end;



Title: Re: Result not being set in class method.
Post by: Thaddy on January 24, 2025, 01:01:09 pm
output is not a good name nor a very smart name for a variable here, since it is also a Pascal reserved word.
It is the same as stdout.
See system.output.
https://www.freepascal.org/docs-html/rtl/system/output.html

And that is definitly not what you mean....

(the old hands seem to be collectively firmly asleep here)
Title: Re: Result not being set in class method.
Post by: bytebites on January 24, 2025, 01:43:05 pm
Output is not reserved word
See the docs https://www.freepascal.org/docs-html/ref/refse3.html
Title: Re: Result not being set in class method.
Post by: Thaddy on January 24, 2025, 02:26:23 pm
It is. It is part of  ISO 7185 which makes it as old as... Pascal.
stdin, stdout  and stderr are not standard, but input, output and erroutput are standard. The former are merely aliases to the real pascal types.
Title: Re: Result not being set in class method.
Post by: bytebites on January 24, 2025, 02:44:55 pm
As your link says it is just variable.
Title: Re: Result not being set in class method.
Post by: Thaddy on January 24, 2025, 03:09:12 pm
No, they are predefined text files. They are an integral part of the language.
So, yes, variables, but very special variables:
program test (input,output);
Title: Re: Result not being set in class method.
Post by: Schmitty2005 on January 25, 2025, 03:23:24 am
@martin_fr Thank you for the thorough explanation!


@Thaddy  Thank you for pointing that out.  I saw no warnings of this in Lazarus or warnings.  My original function was
Code: Pascal  [Select][+][-]
  1. function TGuitarChordBoxCoOrds.getFretMarkerPoint(gString : Integer; gFret : Integer ):Tpoint;
  2. //Do not use optimization .  Use -O- option to view values in IDE
  3. begin
  4.   result := aFingerPoints[gString, gFret];
  5. end;      

But I added the 'output' variable to see if that would fix the problem.  It did not, because it was the optimization that was hiding the values in the IDE.  I recalled seeing a similar issue with FPC and variables not getting calculated as expected, and having to chain the results together.

@Everybody:
I would have thought that Lazarus would have enabled the -O- option by default.  This would have saved me some trouble.  I see that there was no default 'Debug' or 'Release' setups in  Lazarus trunk.  With this being the case, having -O- for the default debug option makes sense most of the time.  Does the official Lazarus install have 'Debug' and 'Release' presets ?  I think that would be helpful, particularly for new users who may not know the quirks of FPC / Lazarus.
Title: Re: Result not being set in class method.
Post by: Martin_fr on January 25, 2025, 09:05:09 am
On the top of project options window is a "build mode" setting. Click/Enter it => there is a button to create release and debug mode.
Title: Re: Result not being set in class method.
Post by: Schmitty2005 on January 25, 2025, 11:58:02 am
On the top of project options window is a "build mode" setting. Click/Enter it => there is a button to create release and debug mode.

Yes, but why are these not defaults in Lazarus ?  With Debug being the active default? I would think most users are using Lazarus to create something, and they will likely need to debug it.

Title: Re: Result not being set in class method.
Post by: dbannon on January 25, 2025, 12:29:14 pm
Yes, but why are these not defaults in Lazarus ?  With Debug being the active default? I would think most users are using Lazarus to create something, and they will likely need to debug it.

In a new project, optimization is -O1, quite low optimization, "debugger friendly". Thats usually enough, maybe you have discovered an exception, perhaps they will name it after you ?

Use of the debugger is also turned on.  The thing missing, IMHO, is heaptrace, I'd advise any project be tested, from time to time for memory leaks. Especially newer users.

Davo

Title: Re: Result not being set in class method.
Post by: Martin_fr on January 25, 2025, 12:44:59 pm
Originally there were no build modes. And then it appears when they were added no one bothered to create new defaults...

You could create a bug report. Not sure how quickly that will or will not be picked up.


There are also other issues, like the "which dwarf do you want question" => Different versions of fpc have different defaults, and the defaults differ for different target OS....
So the IDE does not know what the default is.

Also forcing a common default from the IDE will no always work. And the setting may need to be changed depending on if the user chooses FpDebug or GDB (or LLDB on Mac).

Worse, (and even the current dialog does not manage that). The primary setting (in project options) only affects project files. The LCL has its own settings. So if you debug into the LCL you may have to change those too.... (same for optimization).
Currently that means the IDE will then rebuild the LCL (and other packages). That is slow...

To fix all that is a huge task.
And also not simple, because with all the debug options in existence there would then be a need for several pre-build versions of all of that. But ideally not to increase the download size to double.
And I have no idea how it would affect prebuild closed source 3rd party add ons.

The list goes on and on.
Title: Re: Result not being set in class method.
Post by: PascalDragon on January 26, 2025, 03:56:46 pm
It is. It is part of  ISO 7185 which makes it as old as... Pascal.
stdin, stdout  and stderr are not standard, but input, output and erroutput are standard. The former are merely aliases to the real pascal types.

No, they are predefined text files. They are an integral part of the language.
So, yes, variables, but very special variables:
program test (input,output);

Output and Input are not keywords. Not in TP, not in Delphi, not in FPC and not in ISO Pascal. They are variables. ISO Pascal even explicitly states so in 6.10 (emphasis mine):

Quote
Each program-parameter shall have a defining-point as a variable-identifier for the region that is the program-block.


In FPC, Delphi and TP Input and Output are identifiers in the System unit.
TinyPortal © 2005-2018