Skip to content

Fix an edge case that causes an infinite loop#1

Open
ashak wants to merge 1 commit into
liudr:masterfrom
ashak:master
Open

Fix an edge case that causes an infinite loop#1
ashak wants to merge 1 commit into
liudr:masterfrom
ashak:master

Conversation

@ashak

@ashak ashak commented Dec 21, 2017

Copy link
Copy Markdown

If the number of items in your list is less than the number of items
that can be displayed on screen AND you have the option for
centering the highlighted item on screen enabled it causes an infinite
loop as soon as I try to move from item 0 to item 1

When I move from item 0 to item 1, the variables become:
para->low.i=1
para->high.i=1
items_per_screen=3

So the conditional works out like this:
para->low.i-item_per_screen/2+item_per_screen>para->high.i
1-3/2+3
With integer division in c++ I think that becomes:
1-1+3 = 3
Therefore 3 > 1, and therefore the result is true

Because thats true, _first_item then gets set like this:
_first_item=para->high.i+1-item_per_screen;
1+1-3, which means _first_item = 255.

I couldn't then work out why the following for loop loops infinitely,
but some debugging suggests that it does. So I would imagine i'm
misunderstanding something around how _first_item+item_per_screen is
working in this instance.

If the for loop is
for (byte i=_first_item;i<_first_item+item_per_screen;i++)
i=255
I would expect _first_item+item_per_screen to be
255 + 3, which presumably would equal 2...
The test is 255 < 2, which I would expect to fail and for the contents
of thw loop never to be executed. But that's not what happens

This change ensures that _first_item can't be set in this way if the
number of items in the list is less than the number of items that
can be displayed.

If the number of items in your list is less than the number of items
that can be displayed on screen AND you have the option for
centering the highlighted item on screen enabled it causes an infinite
loop as soon as I try to move from item 0 to item 1

When I move from item 0 to item 1, the variables become:
para->low.i=1
para->high.i=1
items_per_screen=3

So the conditional works out like this:
para->low.i-item_per_screen/2+item_per_screen>para->high.i
1-3/2+3
With integer division in c++ I think that becomes:
1-1+3 = 3
Therefore 3 > 1, and therefore the result is true

Because thats true, _first_item then gets set like this:
_first_item=para->high.i+1-item_per_screen;
1+1-3, which means _first_item = 255.

I couldn't then work out why the following for loop loops infinitely,
but some debugging suggests that it does. So I would imagine i'm
misunderstanding something around how _first_item+item_per_screen is
working in this instance.

If the for loop is
for (byte i=_first_item;i<_first_item+item_per_screen;i++)
i=255
I would expect _first_item+item_per_screen to be
255 + 3, which presumably would equal 2...
The test is 255 < 2, which I would expect to fail and for the contents
of thw loop never to be executed. But that's not what happens

This change ensures that _first_item can't be set in this way if the
number of items in the list is less than the number of items that
can be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant