А так точно можно делать? В смысле, не undefined ли это behavior?
Если строго придерживаться стандарта 
C/
C++, то 
undefined behavior. Но если мы верим в 
IEEE 754, что верно 
почти всегда (я вспомнил, где неверно: в 
IBM S/390, в коде, совместимом с 
S/360), то нет, это вполне правильно и работает.
Вообще, низкоуровневые вещи 
undefined behavior ровно по модулю того, что мы не знаем конкретную аппаратуру. А если знаем, то всё окей, для того они и поддерживаются.
Переносимому коду незачем использовать равенство плавающих чисел.
Переносимость в мире 
IEEE 754 вполне может быть не столь строгой, как "переносимость вообще".
Стандарт разрешает преобразовывать только к char * и void *.
Если явно произнести 
reinterpret_cast, то можно к чему угодно.
отрицательный ноль используется как метка, получается очень удобно, лучше наверное и не придумать
На самом деле, это очень плохая "метка", что все и пытаются вам сообщить.
Кроме того, вы почему-то наивно думаете, что если вы в программе напишете
то у вас и будет создано число "отрицательный ноль", и например, оно будет записано в переменную. Вот тут вас ждёт жестокий 
 облом  разочарование.