__builtin_trap: когда его использовать?
gcc предоставляет дополнительные встроенные функции для оптимизации.
Один из них - void __builtin_trap (void)
, который по существу здесь, чтобы прервать выполнение программы, выполнив незаконную команду.
Из документа:
Функция __ builtin_trap заставляет программу выйти из строя. GCC реализует это с помощью механизма, зависящего от цели (например, преднамеренно выполнение незаконной инструкции) или путем вызова прерывания. Механизм может отличаться от выпуска к выпуску, поэтому вы не должны полагаться на особая реализация.
Зачем вам использовать это, а не exit(1)
или abort
? Почему разработчики gcc рассматривают это как функцию оптимизации?
Ответы
Ответ 1
Потому что exit(1)
заставляет программу нормально завершать код состояния ошибки. См. страницу cppreference. Напротив, __builtin_trap
заставляет программу прерываться аномально.
Самый простой способ увидеть различия - посмотреть на гарантии, сделанные exit
, если сделать одну из этих вещей - это то, чего вы не хотите, __builtin_trap
будет лучше.
Отладка является наиболее распространенным примером, так как __builtin_trap
может заставить отладчик сбрасывать процесс, а exit
не будет (поскольку программа заканчивается "нормально" с ошибкой).
Ответ 2
Функции __builtin
необязательно для оптимизации - они предназначены для "того, что компилятор не может делать непосредственно из исходного кода", включая поддержку "специальных инструкций" и "операций, связанных с архитектурой". Одной из основных целей функций __builtin
является то, что компилятор "знает", что они делают на более позднем этапе. Хотя в компиляторе есть "оптимизация библиотек", компилятор может использовать функции __builtin
гораздо более свободно, чтобы определить, что поведение является чем-то конкретным - например, __builtin_trap
можно полагаться на "не продолжать следующую инструкцию", поэтому компилятору не нужно беспокоиться о коде вроде:
if (x <= 0.0) __builtin_trap();
y = ln(x);
Затем он может использовать "быструю встроенную версию ln
", так как ошибка уже обнаружена.
Отметим также, что __builtin_trap
почти гарантированно заканчивается как "остановка" в отладчике, где exit(1)
или некоторые из них просто выйдут из программы с кодом результата "неуспеха", что довольно неприятно, если вы пытаетесь выяснить, откуда появилось это сообщение с ошибкой...