Решено: Я нашел чистый способ сделать это с setjmp()
/ longjmp()
, требуя только минимальную оболочку, такую как:
int jump(jmp_buf j, int i) { longjmp(j, i); return 0; }
Это позволяет jump()
использоваться в условных выражениях.Итак, теперь код:
if (A == 0) return;
output << "Nonzero.\n";
правильно переведен на:
return
((A == 0) && jump(caller, 1)),
(output << "Nonzero.\n"),
0;
Где caller
- это jmp_buf
назад к точке вызова в вызывающей функции.Чистый, простой и эффективный до степени, которая намного меньше определяется реализацией, чем исключения.Спасибо за вашу помощь!
Есть ли способ эмулировать использование конструкций управления потоком в середине выражения?Возможно ли в выражении x, y
, разделенном запятыми, для y
вызвать return
?
Edit: Я работаю над компилятором для чего-то более аналогичен функциональному языку, а целевой язык - C ++.Все является выражением на исходном языке, и самый простой и понятный перевод на язык назначения оставляет столько выражений, сколько возможно.В основном точки с запятой в целевом языке становятся запятыми C ++.Внутриязычные конструкции управления потоком пока не представляют проблем;это всего лишь return
.Мне просто нужен способ преждевременного выхода из выражения, разделенного запятыми, и я предпочел бы не использовать исключения, если кто-то не покажет мне, что у них нет чрезмерных накладных расходов в этой ситуации.
Проблема, конечно,является то, что большинство конструкций управления потоком не являются допустимыми выражениями в C ++.Единственное решение, которое я нашел до сих пор, это что-то вроде этого:
try {
return
x(), // x();
(1 ? throw Return(0) : 0); // return 0;
} catch (Return& ret) {
return ref.value;
}
Оператор return
всегда существует (в случае, если конструкция Return
не достигнута), и поэтомуthrow
должен быть заключен в ?:
, чтобы компилятор отключился, чтобы его void
результат использовался в выражении.
Я действительно хотел бы избежать использования исключений для управления потоком, если только вв этом случае может быть показано, что никаких особых накладных расходов не возникает;вызывает ли исключение сброс или что-нибудь здесь?Этот код должен работать с разумной эффективностью.Мне просто нужен функциональный эквивалент exit()
.