2016-03-01 3 views
11

gcc предоставляет дополнительные встроенные функции «для оптимизации».__builtin_trap: когда его использовать?

Один из них - void __builtin_trap (void), который по существу здесь, чтобы прервать программу, выполнив незаконную команду.

Из дока:

функция __builtin_trap заставляет программу выйти ненормально. GCC реализует эту функцию с использованием механизма, зависящего от цели (например, намеренно , выполняющего незаконную инструкцию) или путем вызывного прерывания. Используемый механизм может отличаться от выпуска к выпуску, поэтому вы не должны полагаться на какую-либо конкретную реализацию .

Зачем вам это использовать, а не exit(1) или abort? Почему разработчики gcc рассматривают это как функцию оптимизации?

+0

Может быть, для легкой отсрочки откладывания? –

+0

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

+0

Вы имеете в виду вместо 'abort()'? – Barry

ответ

5

Потому что exit(1) заставляет программу нормально завершать код состояния ошибки. См. the cppreference page. В отличие от этого __builtin_trap программа прерывается анормально.

Простейший способ увидеть различия состоит в том, чтобы взглянуть на гарантии, сделанные exit, если сделать одну из этих вещей - это то, чего вы не хотите, __builtin_trap было бы лучше.

Отладка является наиболее распространенным примером, так как __builtin_trap может инициировать отладчик, чтобы сбрасывать процесс, в то время как exit не будет (поскольку программа завершает «нормально» с ошибкой).

+3

'abort' был бы более переносимым способом в обычном убийстве процесса сразу из-за ошибки; '__builtin_trap', я подозреваю, существует, потому что' abort' является библиотечной функцией, и GCC не всегда может рассчитывать на привязку к стандартной библиотеке. –

+0

@ColonelThirtyTwo это приводит к другому вопросу: как бы вы реализовали 'abort'? –

+1

@Revolver_Ocelot glibc на Linux реализует его, удаляя все обработчики сигналов, а затем отправляет процессу сигнал SIGTRAP, который завершает процесс (хотя отладчики обычно ломаются). Затем он также отправляет сам «SIGKILL», а затем бесконечные петли, на всякий случай. Я полагаю, что '__builtin_trap' вместо этого использует команду trap, где она доступна. –

3

Функции __builtin не обязательно для оптимизации - они предназначены для «выполнения действий, которые компилятор не может выполнять напрямую из исходного кода», включая поддержку «специальных инструкций» и «конкретных для архитектуры операций». Одной из основных целей функций __builtin является то, что компилятор «знает», что они делают на более позднем этапе. Хотя в компиляторе есть «оптимизация библиотек», компилятор может использовать функции __builtin гораздо более свободно, чтобы определить, что поведение является чем-то конкретным - например, __builtin_trap можно полагаться на «не продолжать следующую инструкцию», поэтому компилятор не придется беспокоиться о коде, как:

if (x <= 0.0) __builtin_trap(); 
y = ln(x); 

Он может затем использовать «быстрый инлайн версии ln», так как ошибка была поймана уже.

Заметим также, что __builtin_trap почти гарантированно в конечном итоге, как «стоп» в отладчике, где exit(1) или некоторые такие будут просто выйти из программы с «не успех» код результата, который является весьма раздражает, если вы пытаетесь чтобы выяснить, откуда это сообщение математической ошибки ...

+0

Вы можете захватить сигнал ('SIGILL' обычно), что' __builtin_trap() 'генерирует и продолжает выполнение. Например, отладчик может это сделать. Поэтому в общем случае нельзя полагать, что 'x> 0.0' после ловушки. –

+0

Я гарантирую, что компилятор WILL предположит, что '__builtin_trap' не будет продолжаться - да, вы можете его заманить, и вы можете продолжить, но поскольку компилятор этого не ожидает, вы получаете то, что заслуживаете, и оно все равно будет считать 'x> 0.0'. '__Builtin_trap' - это то, как компилятор знает, что вы используете, например,' assert'. –

Смежные вопросы