То, что вы пытаетесь сделать, называется наказанием типа. Есть два традиционных способа сделать это.
Способ сделать это с помощью указателей (что вы сделали). К сожалению, это противоречит оптимизатору. Видите ли, из-за проблемы остановки оптимизатор не может знать в общем случае, что два указателя не накладываются друг на друга. Это означает, что компилятор должен перезагрузить любое значение, которое могло быть изменено с помощью указателя, что приведет к тоннам потенциально ненужных перезагрузок.
Итак, введено правило строгого наложения имен. В основном это говорит о том, что два указателя могут псевдоним друг друга, только когда они одного типа. Как особое правило, char *
может использовать псевдоним любого другого указателя (но не наоборот). Это нарушает типизацию через указатели и позволяет компилятору генерировать более эффективный код. Когда gcc обнаруживает типизацию и включает предупреждения, он предупреждает вас следующим образом:
warning: dereferencing type-punned pointer will break strict-aliasing rules
Еще один способ сделать типизацию - через объединение:
union {
int i;
short s[2];
} u;
u.i = 0xDEADBEEF;
u.s[0] = 0xBABE;
....
Это открывает новую целую банку с червями. В лучшем случае это зависит от реализации. Теперь у меня нет доступа к стандарту C89, но в C99 изначально указывалось, что значение члена объединения, отличного от последнего сохраненного в нем, не указано. Это было изменено в TC, чтобы указывать, что значения байтов, которые не соответствуют последнему сохраненному элементу, не указаны, и в противном случае указывалось, что байты, которые соответствуют последнему сохраненному элементу, интерпретируются повторно в соответствии с тип (что явно зависит от реализации).
Для C ++ я не могу найти язык о взломе union в стандарте. В любом случае, в C ++ есть reinterpret_cast<>
, и это то, что вы должны использовать для обозначения типов в C ++ (используйте ссылочный вариант reinterpret_cast<>
).
В любом случае, вам, вероятно, не следует использовать типизацию (зависит от реализации), и вам следует создавать свои значения вручную с помощью сдвига битов.