__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) или некоторые из них просто выйдут из программы с кодом результата "неуспеха", что довольно неприятно, если вы пытаетесь выяснить, откуда появилось это сообщение с ошибкой...