Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Пусть мы решили написать функцию, которая меняет знак у float, меняя 31-й бит бинарного представления floatи не сказать о том, что так лучше не делать — может быть чревато.
memcpy — наше всё!Ведь union и используется для того чтобы избежать использования указателей.Union — это средство экономии памяти. Точка. Запись в одно поле union'а, а чтение из другого — это неопределённое поведение со всеми вытекащими (вызовом невызываемой фукнции и форматированием винчестера).
union a_union {
int i;
double d;
};
int f() {
union a_union t;
t.d = 3.0;
return t.i;
}
работает. Вот так:int f() {
double d = 3.0;
return ((union a_union *) &d)->i;
}уже нет.char*).memcpy — всё ещё продолжается.У меня для кастов есть темплейтная функция и проблем с ней не замечено на различных компиляторах и платформах.Вам очень хочется дождаться того, чтобы у заказчика отформатировался случайно винчестер? Дождётесь.
union, дальше использовать его для преобразования типов, потом скопировать обратно (что работает в GCC и обычно работает в clang) — так проще уж использовать memcpy и построенный поверх него bitcast.float negate(float num) {
return num * -1;
}return -num;Отключая проходы один за другим, находим искомый
Попробуйте также: https://llvm.org/docs/OptBisect.html
Почему LLVM может вызвать никогда не вызываемую функцию?