Введите тип номера uint32 к указателю структуры? - PullRequest
0 голосов
/ 20 мая 2019

Работая с C, я столкнулся с кодом, который приводит тип uint32 к структуре указателя, я не могу оценить, правильно это или нет, не могли бы вы, ребята, помочь мне с этим?

typedef struct
{
    uint32 a;
    //some other element;
} StructA;

int main()
{
    StructA *a;
    uint32 b;
    b = //assign a value for b;
    a = (StructA*)b;
}

Правильно ли приведен этот тип приведения b к указателю StructA? И, пожалуйста, объясните мне, почему это правильно или неправильно, большое спасибо за вашу помощь

Ответы [ 3 ]

0 голосов
/ 20 мая 2019
 I have encounterd some code which typecase an uint32 number to struct pointer

Адрес первого члена struct и самого struct являются взаимозаменяемыми:

void foo(uint32 *u)
{
    ((StructA *)u)->a = 10;
}

StructA t;
foo((uint32 *)&t);

Но это не означает, что вы можете использовать конкретный тип для инициализацииstruct, в вашем случае:

a = (StructA*)b;

вы используете целое число для инициализации указателя, в результате a указывает на мусор (некоторый случайный адрес).

Существуетв этом нет проблем:

a = (StructA*)&b; // notice the address-of operator

, поскольку a и b имеют одинаковые требования к выравниванию и являются взаимозаменяемыми, но попытка доступа к a->someOtherElement является неопределенным поведением.

0 голосов
/ 20 мая 2019

В общем случае преобразование значения из целочисленного типа в указатель и разыменование указателя имеет смысл, только если оба эти условия выполняются:

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

Например, для 32-битной архитектуры это допустимо C:

StructA *a;
StructA other {};
uint32_t b;
...
b = (uint32_t) &other;
a = (StructA*) b;

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

StructA *a;
StructA other {};
uint32_t b;
...
b = (uint32_t) ...;  // well known address on a specific machine and a specific compiler
a = (StructA*) b;

Требования:

  • машина имеет определенные регистры , начиная с этого хорошо известного адреса
  • конкретная реализация отображает эти регистры в структуру типа *StructA, без проблем с заполнением
0 голосов
/ 20 мая 2019

Этот код выполняет преобразование целого числа в тип указателя. Вот что говорит язык о таком преобразовании:

6.3.2.3 Указатели
...
5 . Целое число может быть преобразовано в любой тип указателя. За исключением случаев, указанных ранее, результат определяется реализацией, может быть неправильно выровнен, может не указывать на объект ссылочного типа и может быть представлением ловушки.

Таким образом, вы должны просмотреть документацию реализации (то есть компилятор), чтобы увидеть, разрешено ли это. Обратите внимание, что этот код не переносим и может привести к неопределенному поведению.

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