конструкция компилятора — Компиляция оператора for из BASIC в Stack Overflow

Я пишу компилятор для переноса какой-либо устаревшей программы VB6 на C ++. Мне нужно перевести for утверждение на языке VB6 в C ++ for заявление:

For var = start To end Step S
...
Next var

Наивный перевод не будет работать, так как S может быть отрицательным:

for (var = start; var <= end; var += S)

Я придумал этот перевод, но троичный if в безобразном состоянии

for (var = start; (S > 0) ? (var <= end) : (var >= end); var += S)

0

Решение

Это сгенерированный код. Вы будете когда-либо только смотреть на это при отладке генератора кода. Так что это совершенно не имеет значения, если это некрасиво. Это имеет значение только в том случае, если оно правильное, и тогда чем проще его генерировать, тем лучше.


Обновление: Однако, если это миграция, возможно, имеет смысл попытаться сделать код читабельным. Тогда я бы либо:

  1. Разрешите оператору использовать его в переводчике, если это возможно, поскольку шаг почти всегда постоянен.
  2. Скройте логику во вспомогательном определении и используйте диапазон для:

    for(auto var : basic_range(start, end, S))
    

    к несчастью повышение :: IRange не сделал это в C ++ 11, и он определен с использованием полуоткрытого диапазона, как обычно для C ++, т.е. end не включен, пока вы хотите включить его. Таким образом, вы должны определить диапазон самостоятельно. По сути, вы бы просто скрыли в нем логику направления, чтобы она не затеняла код. Посмотрите на повышение :: IRange для вдохновения.

В любом случае самой большой проблемой будет жизненный цикл объекта. VB6 (в отличие от предыдущих бейсиков) управляется. Таким образом, вы, вероятно, в конечном итоге будете использовать умные указатели для большинства вещей, и это не самая эффективная вещь.

1

Другие решения

Вы можете избежать троичного выражения в условии завершения, если вы умножаете var а также end по признаку S

int sign = S>=0 ? 1 : -1;
for (int var = start; sign*var <= sign*end; var += S)
{
//...
}
0

По вопросам рекламы [email protected]