Как защититься от недопустимой операции in при попытке получить значение с плавающей запятой из нетипизированного буфера?

#exception-handling #floating-point

#обработка исключений #с плавающей запятой

Вопрос:

Рассмотрим нетипизированный буфер, void* , из которого я беру несколько байтов, чтобы обработать их как значение с плавающей запятой, float или double . Предположим, что значения с плавающей запятой совместимы с IEEE-754 на моей машине. Таким образом, может существовать двоичная последовательность из буфера, которая не представляет никакого допустимого значения с плавающей запятой. Попытка оперировать такой переменной с плавающей запятой, заполненной недопустимым двоичным файлом, приведет к сбою программы.

Как я могу защититься от прерывания программы в таком случае, то есть как я могу получить информацию о недопустимом двоичном коде в переменной с плавающей запятой?

ps. Как правильно извлечь значение с плавающей запятой из нетипизированного буфера? Я слышал, что трюк с объединением, подобный

 void* buf;  
union U {int i; float f;};  
U *u = (U*) buf;  
u->i = binvalue;  
fpvalue = u->f;`
 

недопустимо, даже если buf оно правильно выровнено.

Ответ №1:

Одна из проблем заключается в том, что во многих системах значение с плавающей запятой должно быть выровнено (например, по адресу, кратному 4 байтам), в то время как полностью произвольный указатель может быть не выровнен (и указатель может даже указывать на неотмеченный адрес, например, если он близок к НУЛЮ).

Другая проблема заключается в том, что значения с плавающей запятой IEEE 754 действительно определяют сигнализацию, а не число-s и так далее. Возможно, проверка значений с плавающей запятой с isnan помощью или isinf может помочь.

Наконец, стандарт IEEE 754 настолько сложен, что не каждая система реализует его полностью. Вероятно, вам придется писать очень непереносимый код, если вы хотите быть отказоустойчивым. Хотя я и читал в прошлом этот стандарт, я также забыл ужасную деталь.

Комментарии:

1. Предположим, что буфер правильно выровнен. Я боюсь, что у меня будет прерывание программы еще до того, как мне удастся вызвать isnan , в тот момент, когда я присваиваю двоичный файл переменной с плавающей запятой.