Quote: "This seems to be a highly controversial fix"
I agree too. It's not often that you'll want to change the step value mid-loop, but it does happen. Goorfs code is one example, a sort routine I have is another.
It's also a bit strange that for loops check the step value twice - once to update the counter, and once to ...? maybe to check the loop direction? Can't think of another reason, but why wouldn't you cache the result in a spare register or on the stack and reuse it?
I've knocked together this C++ code to show that there is no need to calculate either the final value or the step value more than once per loop. The assembly that it generates is fairly tight, but it puts the TempStep variable on the stack, when it could probably be kept in EAX while it is needed.
int GetInitial()
{
std::cout << "InitialExpression run\n";
return 1;
}
int GetFinal()
{
std::cout << "FinalExpression run\n";
return 5;
}
int GetStep()
{
std::cout << "StepExpression run\n";
return 1;
}
void DoSomething()
{
int Counter;
int TempStep;
std::cout << "Started loop\n";
Counter = GetInitial();
TempStep = GetStep();
top:
if (TempStep == 0) goto end;
if (TempStep < 0) goto checklower;
if (Counter > GetFinal()) goto end;
goto loop;
checklower:
if (Counter < GetFinal()) goto end;
loop:
// ... User code here ...
std::cout << "===Value of " << Counter << "===\n";
TempStep = GetStep();
Counter += TempStep;
goto top;
end:
std::cout << "Finished loop\n";
}