Подтвердить что ты не робот

Как (вычисляется) goto и longjmp в С++?

Обычно я не кодирую С++, но мой странный друг-компаньон из-за меня устал смотреть на мои замечательные программы FORTRAN и бросил вызов мне переписать один из них на С++, так как ему больше нравятся мои коды на С++. (Мы держим здесь деньги). Точные термины - это то, что их нужно компилировать в современном компиляторе С++. Может быть, он ненавидит хороший conio.h - я не знаю.

Теперь я понимаю, что на С++ есть отличные способы написания, но я собираюсь получить личную победу, пытаясь сделать мою версию на С++ максимально возможной для FORTRAN-esque. Для бонусных очков это может сэкономить время и усилия, когда я конвертирую код.

SO! Это приводит меня к следующим связанным запросам:

На переходах:

  • Как вы работаете с goto?
  • Каковы ограничения на gotos в С++?
  • Любые проблемы с областью? (Я постараюсь максимально расширить сферу действия, но вы никогда не знаете.)
  • Если я использую расширение GCC для перехода в массив указателей void, возникают ли какие-либо новые проблемы в отношении поведения undefined и т.д.?


В longjmp:

  • Как вы можете безопасно использовать longjmp?
  • Каковы ограничения на longjmps в С++?
  • Что он делает с областью видимости?
  • Есть ли какие-то конкретные моменты, когда похоже, что longjmp должен быть безопасным, но на самом деле это не значит, что я должен следить за этим?
  • Как бы я смоделировал вычисленный goto с longjmp?
  • Есть ли какая-то осязаемая польза для использования longjmp over goto, если у меня есть только одна функция в моей программе?

В настоящее время моя главная задача заключается в том, чтобы сделать расчетную работу goto для этого. Похоже, что я, вероятно, буду использовать longjmp для этой работы, потому что массив указателей void не является частью С++, но специальное расширение GCC.

4b9b3361

Ответ 1

Я буду укусить и возьму нижний план.

Я серьезно сомневаюсь, что ваш друг найдет Fortran, написанный на С++, легче (что эффективно, что вы получите, если вы значительно используете goto и longjmp) для чтения, и ему может даже усложниться. Язык С++ довольно отличается от Fortran, и я действительно не думаю, что вы должны попробовать прямое преобразование из Fortran в С++. Это просто упростит работу С++, и вы можете остаться с существующей кодовой базой.

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

longjmp: Нет причин предпочитать longjmp над goto, если у вас есть только одна функция. Но если у вас есть только одна функция, опять же, вы действительно не пишете С++, и вам будет лучше в конечном итоге просто поддерживать ваш Fortran.

Ответ 2

У вас будет много хлопот об использовании goto вообще. Обычно я прыгаю прямо на подножку, но в этом конкретном случае это больше похоже на кодовый гольф для меня. Итак, вы идете.

Используйте goto, чтобы переместить указатель инструкции на "метку" в вашем коде, который является идентификатором С++, за которым следует двоеточие. Вот простой пример рабочей программы:

#include <iostream>
#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    int i = 0;
step:
    cout << "i = " << i;
    ++i;
    if( i < 10 )
        goto step;

}

В этом случае step: - это метка.

Есть проблемы с контекстом.

  • Вы можете использовать только goto для метки в текущей функции.
  • Если ваш goto пропускает инициализацию переменной, вы можете вызвать Undefined Behavior (код, который будет компилироваться, но вы не можете сказать точно что это будет на самом деле.).
  • Вы не можете goto подключиться к блоку try или catch. Однако вы можете goto выйти из блока try.

Вы "можете перейти" с указателями и т.д. при условии соблюдения других проблем. Если рассматриваемый указатель находится в области видимости на узле вызова и в области видимости на сайте ветки, никаких проблем.

Ответ 3

Я думаю, что эта ссылка содержит большую часть информации, которую вы ищете.

перейти

longjmp

Ответ 4

вычислено gotoswitch

Действительно, они используют (общую, но не универсальную) реализацию underling как таблицу перехода.

Ответ 5

Если я понимаю исходный вопрос, вопрос на самом деле интересный. Переписывая вопрос (к тому, что я думаю, является эквивалентным вопросом): "Как вы делаете FORTRAN, вычисленный goto в C?"

Сначала нам нужно знать, что такое вычисленный goto: Вот ссылка на одно объяснение: http://h21007.www2.hp.com/portal/download/files/unprot/fortran/docs/lrm/lrm0124.htm.

Пример вычисленного GOTO:

    GO TO (12,24,36), INDEX

Где 12, 24 и 36 - номера операторов. (Метки языка C могут служить эквивалентом, но это не единственное, что может быть эквивалентом.)

И где INDEX - это переменная, но может быть результатом формулы.

Вот один из способов (но не единственный способ) сделать то же самое в C:

int SITU(int J, int K)
{
int raw_value = (J * 5) + K;

int index = (raw_value % 5) - 1;

return index;
}


int main(void)
{
int J = 5, K= 2;

// fortran computed goto statement: GO TO (320,330,340,350,360), SITU(J,K) + 1
switch (SITU(J,K) + 1)
{
case 0: // 320
    // code statement 320 goes here
    printf("Statement 320");
    break;
case 1: // 330
    // code statement 330 goes here
    printf("Statement 330");
    break;
case 2: // 340
    // code statement 340 goes here
    printf("Statement 340");
    break;
case 3: // 350
    // code statement 350 goes here
    printf("Statement 350");
    break;
case 4: // 360
    // code statement 360 goes here
    printf("Statement 360");
    break;
}

printf("\nPress Enter\n");
getchar();
return 0;
}

В этом конкретном примере мы видим, что вам не нужны C gotos для реализации рассчитанного FORTRAN goto!

Ответ 6

Longjmp может вывести вас из обработчика сигнала, который может быть приятным - и это добавит некоторую путаницу, поскольку оно не будет reset переменными (на основе стека) в функции, которую он долго перескакивает до определения setjmp линия.:)

Ответ 7

Существует расширение GCC, называемое Ярлыки как значения, которые помогут вам закодировать гольф, по сути давая вам вычисленный goto, Конечно, вы можете создавать метки. Вам, вероятно, понадобится это сделать, поскольку вы не можете знать, сколько байтов машинного кода будет генерировать каждая строка.