Kirill A. Shutemov wrote: >> Имеется некая целевая задачка собрать из двух 16-разрядных целых >> вещественное (float), 32 разряда. >> Казалось-бы тривиальная задача, которая решается кодом типа >> int w1 = 62915, w2 = 16456; >> ui32 vl = ((w2&0xffff)<<16) | w1&0xffff; >> //sleep(1); >> printf("TEST 00: %f\n",*(float*)&vl); >> >> И как ожидалось на x86_32 он работает корректно при различной нагрузке. >> А вот на x86_64 замечается ситуация когда вместо 3.14 получаем ноль. >> Причём в тестовой программке с единственным потоком всё работает нормально, >> а на высоконагруженном процессе с десятками потоков, из которых около пяти >> работают с периодом 5мс. устойчиво получатся 0. >> Если раскомментирую sleep, то получаю номальный результат 3.14. >> >> Кто нибуть может такое поведение объяснить? >> > Похоже, вы нарушили strict aliasing. Попробуйте собрать с -Wstrict-aliasing=2. > Если будет ругаться, то это наверно оно(см. оговорку в мане насчёт этой опции). > > Нарушение strict aliasing может сломать некоторые оптимизации. Два выхода -- > или собрать с -fno-strict-aliasing или переписать код корректней. > Я его записывал уже тремя различными способами с одинаковым результатом. :) int w1 = 62915, w2 = 16456; float vl = 0; *(ui16*)&vl = w1; *(((ui16*)&vl)+1) = w2; printf("TEST 00: %f\n",vl); и int w1 = 62915, w2 = 16456; char vl[4]; *(ui16*)vl = w1; *(((ui16*)vl)+1) = w2; printf("TEST 00: %f\n",*(float*)vl); С уважением, Роман