Манипулировать адресом переменной для хранения меньшего типа?

Это то, что я получаю, балуя себя языками программирования высокого уровня.


У меня есть функция, которая записывает 32-разрядное значение в буфер, и uint64_t в стеке. Является ли следующий код разумным способом сохранить его?

uint64_t size = 0;
// ...
getBytes((uint32_t*)&size+0x1);

Я предполагаю, что это будет канонический, безопасный стиль:

uint64_t size = 0;
// ...
uint32_t smallSize;
getBytes(&smallSize);
size = smallSize;

2 ответа

Решение

Нет, он работает правильно только на машинах с прямым порядком байтов. И предполагать, что определенный порядок байтов - даже не проверяя его сначала - не вменяемый.

Даже если вы уверены, что ваша программа сейчас работает только на машинах с прямым порядком байтов, вы никогда не узнаете, может ли она быть запущена на машине с прямым порядком байтов в будущем. (Я пишу это на компьютере, изготовленном компанией, которая десятилетиями использовала процессоры с прямым порядком байтов, затем пару лет назад переключилась на процессоры с прямым порядком байтов, и теперь она также весьма успешна с процессорами с прямым порядком байтов в некоторых устройствах;-))

Почему бы не заставить getBytes() возвращать uint64_t? И используйте аргумент (например, int *), чтобы вернуть код ошибки, если таковой имеется.

Исходя из моего личного опыта, если вы действительно хотите объединить два пути кода, тогда используйте uint64_t в обоих.

Также обратите внимание, что "(uint32_t*)&size" нарушает строгие правила псевдонимов C99 (и, например, в GCC нужно было бы отключить оптимизацию).

Другие вопросы по тегам