Можно привести к указателю указанного типа, определенного во время выполнения в C? - PullRequest
2 голосов
/ 23 июля 2010

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

Я хочу вычислить смещение массива. У меня есть void * ручка к нему и sizeof(element). У меня нет указателя x* (где x - это тип элемента).

Есть ли способ, как я могу привести указатель void * к одному из заданного размера, чтобы я мог делать арифметику указателей на основе этого размера? В данный момент я преобразую в char * (при условии, что char равен 1 байту *), а затем умножаю значение sizeof на смещение. Если бы я мог как-то привести указатель, то я мог бы просто использовать синтаксис массива, который был бы чище.

Как я уже сказал, я на 99% уверен, что это невозможно, и я в основном прошу о представлении типов на уровне языка, которого нет в C. Но стоит спросить.

* И я бы предпочел не потому, что это не всегда так.

Ответы [ 3 ]

4 голосов
/ 23 июля 2010

Как отметили несколько человек в комментариях, sizeof(char) гарантированно равно 1. Соответствующая часть стандарта C99 находится в разделе 6.5.3.4, описывающем оператор sizeof:

Применительно к операнду, который имеет введите char, unsigned char или signed char, (или квалифицированная версия его) результат [из sizeof оператор] равен 1.

Это означает, что приведение void * к char * и добавление N * sizeof(element) является правильным и идиоматическим.

(тип C статически типизирован, поэтому вы не можете привести его к типу, определенному во время выполнения).

2 голосов
/ 23 июля 2010

Вы не можете делать самоанализ в C, но это не мешает вам что-либо приводить в ничто.

void *v = whatever;
char *c = (char*)v;
c[0] = stuff;
element *e = (element*)v;
e[42].foo = bar;

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

char c[x];

где x - переменная, но я бы не стал доверять ей на всех архитектурах.

Вы определенно можете написать пару простых аксессоров для ваших указателей, чтобы хотя бы выделить математическую указатель:

void* pointerAtPos( void*p, int offset, int width )
{
  return (void*)&( ((char*)p)[ offset * width ] );
}

Будьте осторожны с выравниванием адресов .

0 голосов
/ 23 июля 2010

В C приведение является только операцией времени компиляции. Таким образом, невозможно определить фактический тип элемента массива во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...