Указатели на структуру и приведение - PullRequest
0 голосов
/ 09 февраля 2012
Язык

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

/* FILE1.c */
void *mem = ...; //Points to a suitable memory block
struct s1 *p1; //No implementation given for struct s1
void *mem2;

p1 = (struct s1 *)mem;
mem2 = &p1;


/* FILE2.c */
extern void *mem2;
struct s2 { /*...fields...*/ };
struct s2 *p2;

p2 = *(struct s2 **)mem2;

Способен ли этот код работать на всех платформах, при условии, что блок памяти достаточно большой, чтобы содержать struct s2 (например, выделенный malloc(sizeof(struct s2)))?

Другими словами, является ли правильным (т. Е. Переносимым) переосмысление ячейки памяти, содержащей указатель на структуру struct s1, как если бы это был указатель на struct s2?

(Отказ от ответственности): Я прекрасно понимаю, что это очень странный способ играть с указателями, мой вопрос теоретический)

Ответы [ 4 ]

2 голосов
/ 09 февраля 2012

В C указатели не обязательно должны иметь одинаковый размер или представление.

Это означает, что sizeof (int *) может отличаться от sizeof (double *), например.

Единственные требования:

  • void *, char *, signed char * и unsigned char * имеют то же представление.

  • Указатели на структуры имеют одинаковое представление.

  • Указатели на союзы имеют одинаковое представление.

0 голосов
/ 09 февраля 2012

Да, это возможно.

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

0 голосов
/ 09 февраля 2012

Это может быть полезно при абстрагировании некоторых данных. Вы можете иметь:

struct s1
{
  char header[4];
  int  type;
  char data_max[200];
};

struct s1_type1
{
  char header[4];
  int  type;
  char data_of_some_implementation[80];
  char data_of_other_implementation[120];
};

А потом используйте это так

struct s1 data;
int nb = read(fd, &data, sizeof(data));
if (nb == sizeof(data))
{
  if (data.type == 1)
  {
    do_something_special((struct s1_type1*)&data);
  }
}
0 голосов
/ 09 февраля 2012

Да, вы правы. Все указатели имеют одинаковый размер и структуру. Они отличаются только «разумом» компилятора.

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