Thread overview
wierdness in debugger
Mar 30
Enigma
Mar 31
Basile B.
March 30
When debugging a foreach loop that works on an enum constant, the debugger has different behavior if the loop uses brackets or not

The following should demonstrate it:

import std.meta, std.algorithm, std.stdio;
void main()
{
	enum X = AliasSeq!(1,2,3,4,5,3,2,1);
	int y = 0;	
	foreach(x; X)
	   y = max(x, y);
	
	writeln(y);
	
	y = 0;
	foreach(x; X)
	{
	   y = max(x, y);
	}
	
	
	writeln(y);	
}

a BP on the writeln lines will have the debugger skip to the writeln when stepping in the first case and not the second.

It's as if the debugger thinks that the statement after the first max is part of the for each block or something weird like that. Was confusing at first and thought it was a bug because I was getting the wrong value for y. When, in fact, the BP on the writeln simply did not execute the foreach loop completely like it would in the second case, even though it should.

March 31
On Thursday, 30 March 2017 at 17:28:44 UTC, Enigma wrote:
> When debugging a foreach loop that works on an enum constant, the debugger has different behavior if the loop uses brackets or not

Which debugger are you talking about GDB, Mago, LLDB ? linux or windows ? which IDE do you use ?

>
> [...]
>
> a BP on the writeln lines will have the debugger skip to the writeln when stepping in the first case and not the second.

Can you be more clear ?
Let's say i want to reproduce the issue, i put BP on the two writeln, i launch a GDB session, GDB breaks on the first writeln and then ?

>
> It's as if the debugger thinks that the statement after the first max is part of the for each block or something weird like that. Was confusing at first and thought it was a bug because I was getting the wrong value for y. When, in fact, the BP on the writeln simply did not execute the foreach loop completely like it would in the second case, even though it should.


April 01

On 30.03.2017 19:28, Enigma wrote:
> When debugging a foreach loop that works on an enum constant, the
> debugger has different behavior if the loop uses brackets or not
>
> The following should demonstrate it:
>
> import std.meta, std.algorithm, std.stdio;
> void main()
> {
>     enum X = AliasSeq!(1,2,3,4,5,3,2,1);
>     int y = 0;
>     foreach(x; X)
>        y = max(x, y);
>
>     writeln(y);
>
>     y = 0;
>     foreach(x; X)
>     {
>        y = max(x, y);
>     }
>
>
>     writeln(y);
> }
>
> a BP on the writeln lines will have the debugger skip to the writeln
> when stepping in the first case and not the second.
>
> It's as if the debugger thinks that the statement after the first max is
> part of the for each block or something weird like that. Was confusing
> at first and thought it was a bug because I was getting the wrong value
> for y. When, in fact, the BP on the writeln simply did not execute the
> foreach loop completely like it would in the second case, even though it
> should.
>

There is usually a jump instruction at the end of the for/foreach loop to return to the beginning of the loop. In the first loop this instruction does not have a respective token (with attached line info) that matches well in all cases:

- if you choose the "foreach" token, it can be very confusing as the jump instruction can also be the return address of the max() call and shown in the call stack.

- if you choose the next token "writeln" you get the confusion when executing the loop as you describe.

So it's a trade-off. Debugging C++ has the same issue and also sometimes seems to execute the statement after the loop.