Могу ли я контролировать, будет ли gcc размещать код, генерирующий исключения, внутри / снаружи основного тела функции? - PullRequest
1 голос
/ 09 апреля 2019

Учтите это:

void test_throwing_function ()
{
    if (0 == function_1 ())
        throw std::logic_error (__PRETTY_FUNCTION__);

    function_2 ();
}

Я скомпилировал это в GCC (отладочная сборка, без оптимизаций), и, в сокращенном псевдомашинном коде, результат был такой

call function_1
test result, 0
jne do_not_throw
call allocate_exception
call std::logic_error::logic_error
call throw_exception
label do_not_throw:
call function_2
return

Альтернативная реализация будет выглядеть следующим образом

call function_1
test result, 0
je do_throw
call function_2
return
label do_throw:
call allocate_exception
call std::logic_error::logic_error
call throw_exception

Оптимизированная сборка, похоже, использует второй подход, как я и ожидал.

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

Есть ли способ указать gcc использовать второй метод реализации в неоптимизированной сборке?

1 Ответ

0 голосов
/ 11 апреля 2019

Нет, похоже, нет способа сказать gcc сделать это переупорядочение в -O0. Управляется флагом -freorder-blocks:

$ g++ -O 1.c -S -o- | egrep '(ret|call.*logic_error)'
        ret
        call    _ZNSt11logic_errorC1EPKc@PLT

и с -fno-reorder-blocks мы получаем поведение -O0:

$ g++ -O -fno-reorder-blocks 1.c -S -o- | egrep '(ret|call.*logic_error)'
        call    _ZNSt11logic_errorC1EPKc@PLT
        ret

Но флаг действует только в том случае, если оптимизация включена. Вот соответствующая часть из gcc/bb-reorder.c (метод gate прохода указывает, выполнен он или нет):

  virtual bool gate (function *)
    {
      if (targetm.cannot_modify_jumps_p ())
        return false;
      return (optimize > 0
              && (flag_reorder_blocks || flag_reorder_blocks_and_partition));
    }

И действительно, прохождение -freorder-blocks без -O[123s] не имеет никакого эффекта.

AFAIK, это относится к большинству проходов оптимизации. Я не знаю, есть ли причина, по которой пользователь не может выполнить эту оптимизацию на -O0. Вы можете попробовать настроить приведенный выше код и создать собственную версию gcc, чтобы выяснить это; -)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...