Recent

Author Topic: Is there a way to detect "Trash local variables" at compile time?  (Read 13884 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #15 on: July 12, 2018, 04:24:22 pm »
No it does not! If it worked for you that is by accident.
Your "example" only shows that the compiler generates different code for a different CPU.  That's what you're calling an accident. 
It only shows you did not provide full information.....Be careful... Rubbish in, rubbish out.. Popper's falsification hits again... 8-) 8-) :P
BTW: on a 64 bit windows (10.2 developer preview, running updates) , it gets also trashed for a 32 bit executable, so test more carefully. (I suspect you forgot -gt.....you actually deserve a grumpy)
It is not an accident.
« Last Edit: July 12, 2018, 04:30:35 pm by Thaddy »
Specialize a type, not a var.

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #16 on: July 12, 2018, 04:39:03 pm »
And besides, it's inconsistent.
Consistency, as you pointed out, that's the real problem with having -gt fuzz out parameters. 
That always works because you're not assigning one parameter to the other.  You are returning a value, which is not dependent on the other parameter, that should make -gt happy and, as expected, it does.
OK, lets so:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2.  
  3. type
  4.   TR = record
  5.     F: Integer;
  6.   end;
  7.  
  8. var
  9.   Vgbl: Integer = 1;
  10.   Rgbl: TR = (F:1);
  11.  
  12. procedure TestInt(const Vin: Integer; out Vout: Integer);
  13. begin
  14.   Vout := Vin + 1;
  15.   Writeln('In test int: ', Vin);
  16. end;
  17.  
  18. procedure TestR(const Vin: TR; out Vout: TR);
  19. begin
  20.   Vout.F := Vin.F + 1;
  21.   Writeln('In test R: ', Vin.F);
  22. end;
  23.  
  24.  
  25. begin
  26.   TestInt(Vgbl, Vgbl);
  27.   TestR(Rgbl, Rgbl);
  28.   Writeln('Int after: ', Vgbl);
  29.   Writeln('Rec after: ', Rgbl.F);
  30.   Readln;
  31. end.

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #17 on: July 12, 2018, 04:42:39 pm »
And as I said, I'm not the one who called Test(R, R), but the one who writes the Test() procedure. She looks correct. What to do to make it work correctly?

440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #18 on: July 12, 2018, 04:47:46 pm »
No it does not! If it worked for you that is by accident.
Your "example" only shows that the compiler generates different code for a different CPU.  That's what you're calling an accident. 
It only shows you did not provide full information.....Be careful... Rubbish in, rubbish out.. Popper's falsification hits again... 8-) 8-) :P
BTW: on a 64 bit windows (10.2 developer preview, running updates) , it gets also trashed for a 32 bit executable, so test more carefully. (I suspect you forgot -gt.....you actually deserve a grumpy)
It is not an accident.

It's quite unfortunate that you don't have something better to do than whine and expose your ignorance in public. 
(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: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #19 on: July 12, 2018, 04:48:05 pm »
And besides, it's inconsistent.
Consistency, as you pointed out, that's the real problem with having -gt fuzz out parameters. 

The "inconsistency" is in the "const" param (and afaik documented).
Const can pass by ref or value. It is entirely up to the compiler which to choose.

use "constref" if you always want by reference.

Quote
Quote
    "Out O" also is passed by ref. That means if you pass the same variable to R and O, then you are not allowed to change O (because it would change R.
    With -gt you change O.
I don't agree. It's just a side effect.
It may be a side-effect, but that side effect changed the const param (if it is passed by ref). And (according to the doc) you promised to the compiler, that you would write the code in such way that this would not happen (neither directly nor by side effect).



440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #20 on: July 12, 2018, 05:04:45 pm »
And as I said, I'm not the one who called Test(R, R), but the one who writes the Test() procedure. She looks correct. What to do to make it work correctly?
I don't see a clean way of reliably getting around the stack and parameter fuzzer.  I can suggest a horrible hack in assembler but, "horrible" actually falls short of describing it accurately.  Are you even allowed to use assembler in your test routine ?
(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: 14205
  • Probably until I exterminate Putin.
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #21 on: July 12, 2018, 05:07:37 pm »
It's quite unfortunate that you don't have something better to do than whine and expose your ignorance in public.
Oh, well...< people who do understand this is a valid one:  >:D >:D >:D >:D >:D >
If you lack the knowledge don't mix in a discussion.
Specialize a type, not a var.

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #22 on: July 12, 2018, 05:35:13 pm »
I don't see a clean way of reliably getting around the stack and parameter fuzzer.  I can suggest a horrible hack in assembler but, "horrible" actually falls short of describing it accurately.  Are you even allowed to use assembler in your test routine ?
Well, that is called a Stack Canary... (google for it I am fed up with you (at the moment)).
Really, you lack basic knowledge. Now take some classes in compiler engineering....
« Last Edit: July 12, 2018, 05:38:02 pm by Thaddy »
Specialize a type, not a var.

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #23 on: July 12, 2018, 05:37:12 pm »
use "constref" if you always want by reference.
...
It may be a side-effect, but that side effect changed the const param (if it is passed by ref). And (according to the doc) you promised to the compiler, that you would write the code in such way that this would not happen (neither directly nor by side effect).
Once again, the problem is that in code that does not know how it will be used (with the same parameter or not) no protection (warn at compile time) that it cannot be used when using the -gt option.
Constref does not solve the problem, and there are no compiler warnings.

As I understand now there is no such way, and if someone gets an obvious error using my code, then I will explain to him that so use the procedure is not very good, because it is not reflected in the language and documentation as a bad side effect.

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #24 on: July 12, 2018, 05:40:06 pm »
Serge,

I respect your knowledge, but it is not a side-effect. It is the consequence of using out. And that is also basic.
Specialize a type, not a var.

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #25 on: July 12, 2018, 05:59:16 pm »
I respect your knowledge, but it is not a side-effect. It is the consequence of using out. And that is also basic.
Rather the unexpected behavior of the -gt option for out parameters. More precisely, the impossibility to avoid this behavior. After all, this does not happen for var parameters.
In general the out parameter has the following advantages (if you do not care about its original value):
1. The compiler warns you if you try to use it before initialization.
2. No warning if you pass a non-initialized parameter to a procedure.
3. Clear visual description of its use.
But the unexpected behavior pushes away from using these advantages.

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #26 on: July 12, 2018, 06:03:54 pm »
Hence my suggestion for a warning.
The behavior itself is sane.
Specialize a type, not a var.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #27 on: July 12, 2018, 06:10:00 pm »
use "constref" if you always want by reference.
...
It may be a side-effect, but that side effect changed the const param (if it is passed by ref). And (according to the doc) you promised to the compiler, that you would write the code in such way that this would not happen (neither directly nor by side effect).
Once again, the problem is that in code that does not know how it will be used (with the same parameter or not) no protection (warn at compile time) that it cannot be used when using the -gt option.
Constref does not solve the problem, and there are no compiler warnings.
Constref  was about the inconsistency (32 vs 64 bit results).

As for solving your "Test", do not use any const at all.

Again: Currently your code only fails with -gt.
But there is no saying that the exact same code, without -gt will work in future versions of fpc. Maybe some optimization that future fpc will apply makes this exact same code crash.

The problem is in the code (unless you stick with current fpc forever), with or without -gt.  -gt just makes you aware of the problem.


Quote
As I understand now there is no such way, and if someone gets an obvious error using my code, then I will explain to him that so use the procedure is not very good, because it is not reflected in the language and documentation as a bad side effect.
The problem that may not be documented (well it may, but I am not aware off) is how the "out" param works.

That is, that out can (in some cases) pass in the callers variable. So the result of the out param is assigned to the receiving variable while still inside the called procedure; rather than after/at the return from that procedure. In that it acts like a var param.

Yes, -gt doc may also need to be corrected.

======
Maybe there generally is room to lobby for a note/hint from the compiler for any case where the same variable is passed twice or more by reference to the same procedure.
Code: Pascal  [Select][+][-]
  1. function Foo(var a: TBaz; b: TBaz);
  2. ...
  3. Foo(x,x);
  4.  
Probably will also not be "as expected", because inside of Foo any assignment to "a" will also change "b", and vice versa.

In case of out params, it may even be possible to ask, that fpc should generate code passing in a temp variable, whenever it detects that  the out-receiver is passed in at least one more by ref param.
Though passing a temp will change behaviour... (not sure if the documented behaviour would allow for this, did not check that part of the docs)


ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #28 on: July 12, 2018, 06:23:39 pm »
As for solving your "Test", do not use any const at all.
Structure may be big, and input parameter not changed.
So I have to do it not const only because of this behavior?
Quote
But there is no saying that the exact same code, without -gt will work in future versions of fpc. Maybe some optimization that future fpc will apply makes this exact same code crash.
The problem is in the code (unless you stick with current fpc forever), with or without -gt.  -gt just makes you aware of the problem.
Do you think this code is a problematic code?
Code: Pascal  [Select][+][-]
  1. procedure Test(const R: TR; out O: TR);
  2. begin
  3.   O := R;
  4. end;
In fact, the procedure can be quite correctly handle the situation when the const and out parameter is the same (the same memory area), but to report this to the options -gt fails.

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Is there a way to detect "Trash local variables" at compile time?
« Reply #29 on: July 12, 2018, 06:25:33 pm »
As I understand now there is no such way, and if someone gets an obvious error using my code, then I will explain to him that so use the procedure is not very good, because it is not reflected in the language and documentation as a bad side effect.
My tests shows he has a rather liberate opinion of truth... He did not test. I did.
Specialize a type, not a var.

 

TinyPortal © 2005-2018