Битовые сдвиги на указателе C?


Я нахожусь в середине этого проекта C, который я хочу сделать очень эффективным для памяти. В некоторых случаях я использую void * из динамической структуры массива, которую я написал для хранения битов. Я хочу использовать все 64 (в данном случае) бита.

Вскоре я понял, что вы не можете на самом деле делать какие-либо битовые манипуляции с указателем. Итак, мое решение было следующим:

void *p;
((unsigned long)p) << 4;
((unsigned long)p) & 3;

Это делает работу, но только потому, что на моем компьютере длинные и указатели равны по размеру. Будет ли это иметь место в все (или большинство) архитектуры?

И мой реальный вопрос: есть ли более правильный способ делать битовые манипуляции с указателем?Я думал, что этот подход был несколько распространен в C (упаковка битов в пустоту *), но я мог ошибаться...

4 9

4 ответа:

Если ваш компилятор поддерживает его, заголовок C99 <stdint.h> предоставляет типы intptr_t и uintptr_t, которые должны быть достаточно большими, чтобы содержать указатель на вашу систему, но являются целыми числами, поэтому вы можете выполнять битовые манипуляции. Он не может быть намного более портативным, чем этот, если это то, что вы ищете.

Если вам нужно выполнить такого рода манипуляции с указателями, вы можете привести их к intptr_t и uintptr_t, которые можно найти в stdint.h. Они гарантированно определяются как специфичный для платформы целочисленный тип с достаточным количеством битов для хранения указателя.

Там же есть ptrdiff_t, Если вам нужно что-то, чтобы удержать разницу между двумя указателями.

Я думаю, что вы пытаетесь решить неправильную проблему. Настоящая проблема здесь:

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

Не используйте пустые указатели для хранения битов. Используйте пустые указатели для удержания указателей. Используйте целые числа без знака для хранения битов.

Объявляет объединение указателя и битового поля.