Recent

Author Topic: For variable being read after loop... Any way to get an error or warning on it?  (Read 13300 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 15735
  • Censorship about opinions does not belong here.
Thaddy, are you saying that this code will compile under  Delphi 12.1 CE ?
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$IFDEF FPC}{$ERROR Won't compile in FreePascal}{$ENDIF}
  3. begin
  4.   for var i:integer := 0 to 9 do
  5.     writeln(i);
  6.    ....
Yes, Davo,
(I will add you to my list of allowed responses)
You can try that for yourself. The CE edition is free for non-commercial use.
And the scope is confined to the loop scope. Delphi will throw a compiler error if you try to access i after the loop. If you comment out the offending line it compiles and works.
As per my example. Examine everything red in the attached screenshot and shiver.. %)
I might add that some people that are taking part in this discussion never took the trouble to verify what I wrote, which makes them look even more weird than I am. (paraphrasing Harris vs Trump)
« Last Edit: August 11, 2024, 08:17:27 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

440bx

  • Hero Member
  • *****
  • Posts: 4565
Or may be it is a control expression?
Unbelievable.

And what is that "control expression" assigned to ?... because, I case you don't know... an expression is _not_ an lvalue which is required to index the loop.
(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: 15735
  • Censorship about opinions does not belong here.
I also have difficulty with the idiom he has chosen.
Side note: to my surprise Embarcadero still employs at least one decent compiler engineer, but who is it? All the old ones I know (and they know me) but currently I have no clue. :o
He or she must be brilliant, because the compiler code for 32 bit windows - written mostly in C and assembler - is/was almost a riddle and very, very hard to understand.(I have seen versions of it at Borland some decades back)
Delphi is not a self-hosting compiler, unlike Fpc.
« Last Edit: August 11, 2024, 08:41:34 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

Thaddy

  • Hero Member
  • *****
  • Posts: 15735
  • Censorship about opinions does not belong here.
I can not stress enough that taking part in this discussion also may require providing compilable code if you want to make a point, be it in any language.
Just to avoid assumptions all over the place.
If I smell bad code it usually is bad code and that includes my own code.

dbannon

  • Hero Member
  • *****
  • Posts: 3095
    • tomboy-ng, a rewrite of the classic Tomboy
that code works perfectly under Delphi 11 or 12CE.
Thanks !
Quote from: silvercoder70
If you were programming in C in the early 1990s (like me) you would have used the sloppy version of code. It's not ugly, it's just the way it was.
Yep, I can confirm that too. I think the in line declaration was a relatively late addition to C. And a good addition.

Now, I had a quick search of our wiki, looking for pages about "for loops", I found three and not one mentioned the issue under discussion here. That surprises me.



So, it is a bit like Thaddy suggested, its necessary to have something like this that a new user does not expect and will (probably) only find out when they ask an old timer why their code crashes. Other wise, they won't have any respect for the old timers.

(If we really think this way, we won't have any new users before long ....)

Davo


Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

MarkMLl

  • Hero Member
  • *****
  • Posts: 7713
So, it is a bit like Thaddy suggested, its necessary to have something like this that a new user does not expect and will (probably) only find out when they ask an old timer why their code crashes. Other wise, they won't have any respect for the old timers.

Without wanting to detract from Thaddy's arguments and examples, it's a point I've been trying to make for some while.

Apropos the "control variable" argument, I think the point is that irrespective of whether C (or Pascal) has one, C doesn't have the situation where a variable being used to control a loop suddenly assumes no defined value.

As an historical note, ALGOL (-60) assumed that variables were declared /in/ a block, rather than /prior to/ a block. I can't remember what the semantics were when a variable declared in a nested block went out of scope.

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

dbannon

  • Hero Member
  • *****
  • Posts: 3095
    • tomboy-ng, a rewrite of the classic Tomboy

Thanks for adding me to your "will respond list" Thaddy, I will hold you to that !   8-)

So, we have every reason to fix these problems, but no indication why its not happening ?  Sigh ...

Davo


Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

Thaddy

  • Hero Member
  • *****
  • Posts: 15735
  • Censorship about opinions does not belong here.
Well, the compiler devs usually have read this, but I don't want to post a duplicate on the bug-tracker. ( actually a multiplicate )
If I smell bad code it usually is bad code and that includes my own code.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5690
  • Compiler Developer
So, we have every reason to fix these problems, but no indication why its not happening ?  Sigh ...

If you want it so badly, then why don't you do it yourself instead of expecting us core devs, who have only so much time to work on FPC and tend to spend that for more important things, to do it just right now?

alpine

  • Hero Member
  • *****
  • Posts: 1263
Try to compile this:
Code: C  [Select][+][-]
  1. void main()
  2. {
  3.         for(;;);
  4.                
  5.         while();
  6. }
:D
Okay, there is a little catch (from the docref in reply #104):
Quote
Both clause-1 and expression-3 can be omitted. An omitted expression-2 is replaced by a nonzero constant
and also the whole thing should be enclosed in a curly braces in case the clause-1 is a declaration. ;)

.... and there's many millions of lines of legacy Pascal that rely on it. ...

I cannot imagine code that relies on a value being undefined.  Can anyone offer an example ?

Davo
I've just checked TP7. There is no limitation not to assign the control variable inside the loop. See the attachment pic.
It is quite possible that someone used that kind of assignment instead of a break. Just speculating.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

tetrastes

  • Hero Member
  • *****
  • Posts: 540
I've just checked TP7. There is no limitation not to assign the control variable inside the loop.

It's allowed in fpc with {$mode tp} also.

dbannon

  • Hero Member
  • *****
  • Posts: 3095
    • tomboy-ng, a rewrite of the classic Tomboy
I've just checked TP7. There is no limitation not to assign the control variable inside the loop. See the attachment pic.
It is quite possible that someone used that kind of assignment instead of a break. Just speculating.

Nice to know but I don't think thats one of the key issues here, generally, we do accept we can no longer fiddle with the control variable inside the for loop.  Its more -
  • Issue a compiler warning that programmer seems to be assuming they can use the value assigned to the variable inside the "for loop", outside the loop - a pretty reasonable request.
  • And/or safely use that value - a forlorn hope.
  • Declare, in-line a "for loop" control variable, a reasonable but also apparently forlorn hope too.

    Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

alpine

  • Hero Member
  • *****
  • Posts: 1263
@dbannon, @MarkMLl
With regard with the other thread https://forum.lazarus.freepascal.org/index.php/topic,43172.msg526941.html#msg526941
and the Davo's question earlier https://forum.lazarus.freepascal.org/index.php/topic,68067.msg526337.html#msg526337

I'm still scratching my head trying to find an example of using the value of the control variable after the loop. From my POV  for is either a full iteration with no variable access after it, or the control variable is taken into the loop, e.g.
Code: Pascal  [Select][+][-]
  1. result := -1;
  2. for i := 0 to high(a) do
  3.   if a[i] = x then
  4.   begin
  5.     result := i;
  6.     break;
  7.   end;
  8. if result > -1 then
  9.   {found};

But may be this can be written as:
Code: Pascal  [Select][+][-]
  1. for i := 0 to high(a) do
  2.   if a[i] = x then
  3.     break;
  4. if a[i] = x then
  5.   {found};
And that is a problem when the x value is not present.

Perhaps Mark, as a proponent of the inline control variable, can provide a few more examples he's come across.

What about the control variable of for..in..do?
https://www.freepascal.org/docs-html/ref/refsu59.html
I couldn't find anything about the undefined value, just the assignment restriction.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

MarkMLl

  • Hero Member
  • *****
  • Posts: 7713
Perhaps Mark, as a proponent of the inline control variable, can provide a few more examples he's come across.

You might equally scratch your head over a gross type error (rejected as an error by the compiler), or misapplication of a signed type when the use case is crying out for an unsigned.

Without wanting to sound as though I'm attempting to apply ill-informed pressure on the FPC maintainers, this is something that the compiler /should/ warn about, but does /not/ warn about.

Allowing a properly-bounded local variable, similar to that belatedly added to C, would sidestep that by ensuring that the control variable went out of scope as soon as there was a possibility it was no longer defined. At that point the compiler could warn that usage of the legacy form (i.e. control variable declared at the head of the function) risked undefined behaviour, and could also detect the case where the locally-declared control variable had the same name as a variable in the surrounding scope and could warn the user appropriately.

That would move the fix from being DFA Deep Magic, to relatively straightforward compiler warnings extending those already in use.

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

dbannon

  • Hero Member
  • *****
  • Posts: 3095
    • tomboy-ng, a rewrite of the classic Tomboy

and the Davo's question earlier https://forum.lazarus.freepascal.org/index.php/topic,68067.msg526337.html#msg526337

My question was more specific than you seem to think, I was asking for an example of code that depended on the variable being undefined.

My argument being that removing that 'undefined' characteristic (and doing what many users expect) cannot possibly do anyone any harm. Whether its worth the added complexity is another question of course.

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

 

TinyPortal © 2005-2018