Представление ловушки - это универсальный термин, используемый C99 (IIRC не C89) для описания битовых комбинаций, которые вписываются в пространство, занимаемое типом, но запускают неопределенное поведение, если используются в качестве значениятакого типаОпределение дано в разделе 6.2.6.1p5 (с щупальцами во всем 6.2.6), и я не собираюсь его здесь цитировать, потому что оно длинное и запутанное.Тип, для которого существуют такие битовые комбинации, называется «имеющим» представления ловушек.Не требуется, чтобы тип имел какие-либо представления ловушек, но единственный тип, который стандарт гарантирует, что не имеет представления ловушек, это unsigned char
(6.2.6.1p5, 6.2.6.2p1).
Стандарт дает два гипотетических примера представлений ловушек, ни один из которых не соответствует чему-либо, что какой-либо реальный процессор делал в течение многих лет, поэтому я не собираюсь вас с ними путать. хороший пример представления прерываний (также вещь only , которая квалифицируется как представление прерываний аппаратного уровня на любом процессоре, с которым вы, вероятно, столкнетесь) - это сигнальный NaN в плавающемтип точки.Приложение F C99 (раздел 2.1) явно оставляет поведение сигнальных NaN неопределенным, даже несмотря на то, что МЭК 60559 подробно описывает их поведение.
Следует отметить, что в то время как типам указателей разрешено иметь представления ловушек, нулевые указатели не представления ловушек.Нулевые указатели вызывают неопределенное поведение, только если они разыменованы или смещены;другие операции над ними (главное, сравнения и копии) четко определены.Представления ловушек вызывают неопределенное поведение, если вы просто читаете их, используя тип, который имеет представление ловушек.(Является ли недействительным , но ненулевые указатели считаются или должны считаться представлениями ловушек, является предметом обсуждения. Процессор не обрабатывает их таким образом, но компилятор может.)
Код, который вы показываете, имеет неопределенное поведение, но это из-за правил наложения указателей, а не из-за представлений ловушек.Вот как конвертировать float
в int
с тем же представлением (при условии, как вы говорите, sizeof(float) == sizeof(int)
)
int extract_int(float f)
{
union { int i; float f; } u;
u.f = f;
return u.i;
}
Этот код имеет неопределенный (неundefined) поведение в C99, что в основном означает, что стандарт не определяет какое целое значение создается, но вы действительно получаете некоторое действительное целое значение, это не представление ловушки, иКомпилятору не разрешено оптимизировать, если вы этого не сделали.(Раздел 6.2.6.1, параграф 7. Моя копия C99 может включать в себя технические corrigienda - я помню, что это было неопределенным в исходной публикации, но было изменено на неопределенное в TC.)